Страницы

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

понедельник, 6 января 2020 г.

Отказано в доступе при использовании Directory.GetFiles

#c_sharp #net #файлы


Я хочу получить список файлов, которые находятся во вложенных директориях и использую:

Directory.GetFiles(string,string,SearchOption)


Но через какое-то время я получаю ошибку: "Отказано в доступе".

Я посмотрел в дебагере и обнаружил, что Directory.GetFiles натыкается на какие-то
скрытые системные папки, которые мне в принципе не нужны.

Можно ли как-нибудь задать игнорирование подобных папок?

Если я оберну все в try/catch, то боюсь, что я не получу нужны мне список.
    


Ответы

Ответ 1



Взял отсюда private List GetFiles(string path, string pattern) { var files = new List(); try { files.AddRange(Directory.GetFiles(path, pattern, SearchOption.TopDirectoryOnly)); foreach (var directory in Directory.GetDirectories(path)) files.AddRange(GetFiles(directory, pattern)); } catch (UnauthorizedAccessException) { } return files; } Функция рекурсивная. При составлении списка файлов будут учитываться обыкновенные папки, а системные не учитываться. Не должно быть такого, что из-за Eхception в конечный результат не войдут обыкновенные файлы. Console.WriteLine("Started: " + DateTime.Now.ToLongTimeString()); var fileList = GetFiles("c:\\", "*.*"); Console.WriteLine("Finished: " + DateTime.Now.ToLongTimeString()); Console.WriteLine("Files count: " + fileList.Count); // У меня так: // Started: 12:43:05 // Finished: 12:44:33 // Files count: 427083

Отправка команд на компьютер из Android приложения

#android #cpp #windows #приложение


Здравствуйте, у меня такой вопрос.
Возможно ли из своего Android приложения отправлять команды на компьютер (через Wi-Fi
или Bluetooth), на котором так же будет установлена программа принимающая данные команды
(на C++ к примеру) ?

Если имеет значение ОС на компе, то интересует Windows.

Что бы вы могли представить себе более понятно что имеется в виду, представьте себе
что Android приложение это как пульт для телевизора, то есть пользователь выполняет
действия, на комп отправляется команда, а там уже другая программа выполняет эти действия.

Я предполагаю что это возможно, но вот проблема в том что не могу найти как это реализовывается.
Могли бы вы подсказать в какую сторону копать что бы понять как такое можно сделать ?
В какую сторону искать что бы понять как с android приложения отправлять команды,
и в какую сторону искать что бы понять как их принимать на  С++ ?

Спасибо.
    


Ответы

Ответ 1



В случае если компьютер и девайс находятся в одной сети все предельно просто. На компьютере запускается приложение которое прослушивает определенный заранее выбранный порт, например по протоколу UDP. Порт можно выбрать любой от 1 до 65'535, обычно рекомендуют для домашнего использования больше 60'000, т.к. они обычно не заняты. Далее на девайсе посылаем бродкаст на выбранный порт с командой. В самом простом случае это может быть строка с кодовым словом или вообще JSON. Преимущество UDP в том что не обязательно указывать ip адрес получателя, сообщение разошлется по всей сети, но поймет его только тот кто слушает выбранный порт и знает формат команды.

Ответ 2



На C пишется Web-серверер (или используется готовый), на андроиде приложение отправляет ему GET/POST-запросами команды. Я, правда, сразу вижу проблему определения адреса сервера... Можно обойтись и без специального приложения на Android, если все действия будут в браузере выполняться.

Ответ 3



Такое можно написать на сокетах (использовать TCP/IP протокол). Android будет выступать сокет-клиентом, а сервер - сокет-сервером. В таком случае не только Andorid может посылать команды, но и сервер! Реализовать на Web-сервере (протокол HTTP). Кстати, например, вот бесплатный многопоточный веб-сервер: https://github.com/sitev/cjNetwork (сам писал ))) ). Можно взять другой бесплатный, более надёжный, например, мангуста: https://github.com/cesanta/mongoose CGI/FastCGI/SCGI

Ответ 4



Можно через Jabber ботов организовать, можно даже через email

Как добавить игнор лишних файлов в репозиторий github?

#git #github #gitignore


Я создал репозиторий под проект на Java, но не выбрал настройку файла gitignore под
Java-проект.
Как добавить игнор лишних файлов под проект Java в репозиторий github?
    


Ответы

Ответ 1



Создайте в корне файл .gitignore: *.class # Mobile Tools for Java (J2ME) .mtj.tmp/ # Package Files # *.jar *.war *.ear # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* Java.gitignore .gitignore для остальных языков и фреймворков

Расчет количества слов в тексте

#cpp


Необходимо подсчитать количество вхождений каждого слова в тексте.


словом считается любая последовательность символов, каждый из которых не входит в
множество разделителей. Множество разделителей должно задаваться отдельно (строкой).
кодировка - символы однобайтовые
текст находится в файле, имя файла задается первым аргументом командной строки
пример:
test.exe war_and_peace.txt
выводить в stdout, формат <слово> - <сколько раз встретилось>, вывод должен быть
отсортирован по словам в лексикографическом порядке


Допустим есть строка и множество разделителей:

void main()
{
    string mySentense = "one. two three one, one two";
    string spacersЗlurality[] = { ",", "." };
}


Подскажите как хотя бы сделать 4 пункт?
    


Ответы

Ответ 1



Вот демонстрационная программа, которая показыывает один из возможных подходов к решению задания в соответствии с пунктом 4. #include #include #include #include int main() { std::string mySentense = "one. two three one, one two"; const char *delimiters = "., \t"; std::map frequencies; for ( std::string::size_type pos = 0; ( pos = mySentense.find_first_not_of( delimiters, pos ) ) != std::string::npos; ) { auto n = pos; pos = mySentense.find_first_of( delimiters, pos ); std::string word = mySentense.substr( n, pos == std::string::npos ? pos : pos - n ); for ( char &c : word ) c = std::toupper( ( unsigned char )c ); ++frequencies[word]; } for ( const auto &p : frequencies ) std::cout << p.first << ": " << p.second << std::endl; } Вывод программы на консоль: ONE: 3 THREE: 1 TWO: 2 Все, что вам еще нужно сделать, так это считывать файл строка за строкой, используя стандартную функцию std::getline

Грамотное кэширование в NodeJS проекте

#nodejs #кэширование #redis #highload


Планируется highload-проект с использованием NodeJS, MySQL, Redis, NGINX.
За основу взят nodejs фреймворк express, и для работы с сокетами (может это и не
хорошее решение) - socket.io. Проект представляет собой single page application, предполагается,
что сокет-соединение будет открыто повсеместно. Будет большое количество страниц, которые
являются статистично-информативными, и не щадят бд тяжелыми запросами.

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


Например, есть запрос к БД, его результат мы можем сохранить в Redis в виде JSON,
при следующих обращениях уже будем брать его из Redis и, когда необходимо - делать
инвалидацию данного кэша. - Насколько правильно это? И стоит ли именно в JSON хранить
данные?
Нам иногда нужна закэшированная страница не только в JSON, а кусок или целиком HTML.
- Правильно ли хранить эти куски в Redis?
Есть идея реализовать session-storage в Redis, как это сделать правильно? например
ключом будет id сессии, а значением - массив данных о клиенте. - Это правильно или
нет? Как будет лучше?
В каких случаях стоит записывать кэш в файлы на диск?
Стоит ли вообще пихать все что выше описано в redis? 


Я не имею опыта в highload, поэтому мне интересно все, что вы скажете, очень нужны
грамотные советы в построении проекта на перечисленных компонентах. Может, есть какие-то
рекомендации по работе с сокетами в highload, либо еще что-то, что касается основ такого
проекта. 

Признателен за ваши полезные советы, благодарю за внимание!
    


Ответы

Ответ 1



Например, есть запрос к БД, его результат мы можем сохранить в Redis в виде JSON, при следующих обращениях уже будем брать его из Redis и, когда необходимо - делать инвалидацию данного кэша. - Насколько правильно это? На сто процентов, но своевременная инвалидация кэша - довольно большой челлендж. И стоит ли именно в JSON хранить данные? Вообще меня несколько коробит сохранять данные строкой, но особого выбора нет, и вообще это не должно влиять ни на что. Нам иногда нужна закэшированная страница не только в JSON, а кусок или целиком HTML. - Правильно ли хранить эти куски в Redis? Нет, у вас же SPA, весь рендеринг должен быть на клиенте. Есть идея реализовать session-storage в Redis, как это сделать правильно? например ключом будет id сессии, а значением - массив данных о клиенте. - Это правильно или нет? Как будет лучше? Если сессия у вас считается за постоянное хранилище, то неправильно, потому что Redis не предназначен для постоянного хранения данных (хоть и умеет время от времени скидывать данные на диск). Вместо этого лучше организовать двухуровневое (или даже трехуровневое) хранилище из связки Redis - БД (In-Memory - Redis - БД в случае трехуровневой связки). В каких случаях стоит записывать кэш в файлы на диск? Как правило, ни в каких, есть база данных. Туда можно скидывать результаты тяжелых запросов, чтобы все ноды их видели, но даже в этом случае я бы организовывал промежуточный Redis-слой. Стоит ли вообще пихать все что выше описано в redis? Чем больше будет висеть в кэше, тем лучше, но время от времени посматривайте на количество съедаемой оперативной памяти. Может, есть какие-то рекомендации по работе с сокетами в highload, либо еще что-то, что касается основ такого проекта. Помните про две вещи Проект обязан масштабироваться горизонтально, т.е. простым добавлением новых серверов. Из этого вытекает, что изменения на одном сервере должны быть видны для всех остальных (это достигается за счет использования одного Redis и БД) Существует такая штука, как dogpile effect, который означает кучу пользователей, одновременно запросивших один и тот же ресурс. В случае с вышеописанным трехуровневым хранилищем сто синхронно пришедших пользователей не обнаружат запись в кэше и ломанутся (все сто) к БД. В случае, если в БД 20 одновременных подключений, и каждый запрос занимает 30мс, то последний пользователь получит данные не раньше, чем через 150мс (это в идеальном случае, на самом деле там будет значительно большее число), что очень нехорошо.

Что делает данный кусок кода? $(“#table”,$(“.someth”))

#javascript #jquery


Попался возник вопрос в собеседовании: что делает этот кусок кода

$("#table",$(".someth"))


На мой взгляд - это бред, с помощью поиска и документации так же не смог найти.
    


Ответы

Ответ 1



Согласно документации второй параметр - контекст селектора. То есть выполняется как бы подзапрос. Этот вызов аналогичен $(".someth").find("#table"); Соответсвенно будут найдены все элементы с классом someth и, затем, внутри них элементы c id равным table. Страница документации (по-английски); Описание по-русски.

Ответ 2



Пример группового селектора, возвращает набор из элементов, которые удовлетворяют одному из селекторов

Dispatcher не запускает метод в нужном потоке

#c_sharp #wpf #многопоточность


У меня есть WPF окно, по событию которого вызывается комманда ViewModel. Она в свою
очередь вызывает метод из BAL, запускающий дочерний поток(может жить от 10 сек до бесконечности).
Данный поток генерирует события по мере выполнения и еще одно событие в самом конце,
извещающее о конце работы. Тк события происходят не основном потоке, то ViewModel использует
Dispatcher для синхронизации. Если я что-то на проектировал не так, буду рад узнать.
Для выполнения кода в нужном потоке я использую следующий код

Dispatcher.CurrentDispatcher.BeginInvoke(new Action(SomeMethod));


Но этот код не вызывает мне нужный метод в обще. Далее я попробовал вызвать следующий код

Dispatcher.CurrentDispatcher.Invoke(new Action(SomeMethod));


В итоге я все равно получил ошибку, тк выполнение не в главном потоке.
Тестирования ради я объявил поле _dispatcher и инициализировал его в конструкторе
в время работы главного потока. Данный диспетчер мне уже все спокойно вызывал.
С чем это связано и как мне быть? Если я вдруг создам ViewModel не в главном потоке,
то у меня опять работать ничего не будет.
    


Ответы

Ответ 1



Смотрите. Dispatcher.CurrentDispatcher возвращает вам диспетчер для данного потока. Поэтому у вас нету альтернативы хранению ссылки на диспетчер. Затем, VM-объекты обязаны бежать в UI-потоке (иначе вы не сможете биндить к ним View), так что они должны конструироваться тоже в UI-потоке. А значит, вы вполне можете рассчитывать на то, что уж в конструкторе у вас будет правильный Dispatcher.CurrentDispatcher. Почему не работает диспетчер, созданный в фоновом потоке? Диспетчер — это абстракция над циклом сообщений. Если в данном потоке бежит цикл сообщений, то Dispatcher.CurrentDispatcher его вам и возвращает. Если же для данного потока диспетчера нету, создаётся новый и прикрепляется к данному потоку. Но этот диспетчер ещё не запущен! Команда лежит в очереди и дожидается. Если вы запустите диспетчер в фоновом потоке, то все команды, отосланные ему, будут выполнены. Однако, не пытайтесь сделать это в потоке из пула потоков: для работы диспетчера поток должен быть STA, а потоки из пула — не STA (и это нельзя поменять). Ну и по-хорошему обычно вам должно хватать диспетчера в UI-потоке.

MySQL обрезает текст на сложном символе-картинке

#php #mysql #кодировка


Столкнулся со следующей проблемой. Имеем текст

Текст Текст Текст Текст 💲

При вставке в базу MySQL текст обрезается по символ 💲, то есть остается

Текст Текст Текст Текст 


Вставка происходит в коде php:

$text = PHP_slashes($text); // экранируем кавычки
$sql = table}` (`text`) VALUE ('$text')"; $this->db->execute($sql); Попробовал вставить вручную в базу это сообщение - все сработало, только 💲 заменился на ?. Такое поведение вполне устраивает, можно бы и вовсе удалить такие символы из сообщения. Аналогичная проблема на символах 👍 🚑 🎁 и т.д. Можно ли как-то поправить настройки базы или что-то сделать в коде php, чтобы такие символы переводились в ? или удалялись ? P.S.: Больше интересует не конкретное решение замены символов в строке, а настройки на все случаи - чтобы база не резала текст, а как-то его сохраняла, заменяя непонятные ей символы. Update: строка запроса INSERT INTO `mails` (`text`) VALUE ('

Текст Текст Текст Текст \"💲\"

') Только вместо 💲 в текстовом файле отображается квадратик с вопросом


Ответы

Ответ 1



Ваша база сейчас работает в кодировке utf-8 в которой на 1 символ максимум выделяется 3 байта. Из-за этого ваши фигурные символы (а так же символы китайского и японского языков) не могут быть записаны в базу, так как имеют размер 4 байта. Следует перевести базу данных на работу в кодировке utf-8 с поддержкой символов размером до 4 байт. Если MySQL имеет версию ниже 5.5.3, его следует обновить. Сделать полный бекап базы данных. Для перевода базы на 4-x байтный utf-8 нужно выполнить команду ALTER DATABASE название_базы CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci; Для каждой таблицы базы нужно выполнить команду такого вида ALTER TABLE название_таблицы CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; Для каждого поля содержащего текстовую информацию в каждой таблице нужно выполнить команду (примерный вид, зависит от структуры поля) ALTER TABLE название_таблицы CHANGE название_столбца название_столбца VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; Пункты 3-5 можно выполнить например через phpmyadmin. В код php нужно добавить сразу после коннекта к базе выполнение запроса вида SET NAMES 'utf8mb4' COLLATE 'utf8mb4_general_ci' P.S. Про установку кодировки соединения https://ru.stackoverflow.com/a/726863/186083

Ответ 2



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

Ответ 3



Нашел решение. Не совсем то, что хотелось, но пока что работает, хотя я буду ждать более нормальные варианты. function clearText($text) { $text = iconv('utf-8', 'windows-1251//IGNORE', $text); $text = iconv('windows-1251', 'utf-8//IGNORE', $text); return $text; } Эта функция убирает все "фигурные" символы из текста. Решение типа $text = iconv('utf-8', 'utf-8//IGNORE', $text); не работает.

Контроль версий для файлов MS Office, Libre Office и других XML-based

#git #git_config


Хочу хранить в репозитории Git файлы из офисных пакетов вроде MS Office или Libre Office.


Возможны ли какие-то проблемы?
Как правильно организовать хранение? 
Можно ли производить слияние (merge) этих файлов средствами Git? 

    


Ответы

Ответ 1



Возможны ли какие-то проблемы? Есть ряд форматов данных, которые внутри себя устроены как папки/архивы, содержащие текст (xml) и бинарные данные. Список XML-based форматов просто огромен, приведу одни из самых популярных: OpenDocument: .odt, .ods, .odp и прочие. OpenOffice.org XML: .sxw, .sxc, .sxi и прочие. Open Packaging Conventions .docx, .xlsx, .pptx и прочие. Git может распознавать такие файлы как текст. Тогда он Начнет приводить к общему виду окончания строк, При слиянии ветвей соберет один документ из двух, рассчитывая на дальнейшую ручную правку. То и другое испортит файл почти необратимым образом. Из документации Git: gitattributes, "Marking files as binary". Git usually guesses correctly whether a blob contains text or binary data by examining the beginning of the contents. However, sometimes you may want to override its decision, either because a blob contains binary data later in the file, or because the content, while technically composed of text characters, is opaque to a human reader. Как правильно организовать хранение? В корневой директории проекта нужно создать файл .gitattributes (или отредактировать, если уже есть). В него добавить следущую строку — для каждого расширения файлов, которое там будет храниться: *.<расширение> binary Пример: *.docx binary *.xlsx binary *.odt binary Таким образом вы явно отмечаете, что файлы с данным расширением необходимо обрабатывать как бинарные. В бинарном файле Git никогда не будет заменять окончания строк (т.к. для него это теперь не CR и LF, а просто байты). Можно ли производить слияние (merge) этих файлов средствами Git? Если .gitattributes настроен правильно, то можно производить слияние веток, содержащих такие файлы. При слиянии документ не будет испорчен, но и объединить содержимое двух файлов в один автоматически не получится. Однако, PashaPash подсказывает, что в MS Office есть специальный инструмент для слияния файлов. После того, как вы вручную собрали из двух документов один (или выбрали одну из версий), нужно проиндексировать изменения и подтвердить их коммитом, чтобы завершить слияние.

Как узнать какой тип Fragmenta в Android?

#java #android


Всем привет.

Есть три вида Фрагментов.

    ArtistFragment artistFragment = new ArtistFragment();
    AlbumFragment albumFragment = new AlbumFragment();
    SongFragment songFragment = new SongFragment();


Fragment один из трех выше предложенный возвращается с помощью функции.

Fragment fragment = pagerAdapter.getItem(position);


Как узнать какой Fragment вернулся? Смутно помню в Java была такая функция instanceOF?
    


Ответы

Ответ 1



Есть два способа узнать класс фрагмента. Можно, как вы сами уже сказали, методом instanceof: Fragment f = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container); if (f instanceof CustomFragmentClass) //что-то сделать с f А можно прикреплять к фрагменту специальный тэг, который будет уникальным для фрагмента каждого типа: fragTrans.replace(android.R.id.content, myFragment, "MY_FRAGMENT"); В последствие, по этому тэгу вы сможете понять тип фрагмента: MyFragment f = (MyFragment)getFragmentManager().findFragmentByTag("MY_FRAGMENT"); if (f!= null && f.isVisible()) //что-то сделать с f

Ответ 2



Да, можно с помощью instanceof. Например Fragment fragment = pagerAdapter.getItem(position); if(fragment instanceof SongFragment) { //SongFragment } else { //другой фрагмент} Ещё можно имя класса получить так: Fragment fragment = pagerAdapter.getItem(position); String className=fragment.getClass().getSimpleName();

Ответ 3



ну да можно: Fragment fr = pagerAdapter.getItem(position); if ( fr instanceof ArtistFragment) { // } else if ( fr instanceof AlbumFragment) { // } else if ( fr instanceof SongFragment) { // } а можно простой проверкой класса: Fragment fr = pagerAdapter.getItem(position); if ( fr.getClass() == ArtistFragment.class) { // } else if ( fr.getClass() == AlbumFragment.class) { // } else if ( fr.getClass() == SongFragment.class) { // }

Ответ 4



Да конечно можно проверить с помощью instanceof, получится что то вроде Fragment fragment = pagerAdapter.getItem(position); if (fragment instanceof ArtistFragment) { ...; } else if (fragment instanceof AlbumFragment){...} Но вроде как использование instanceof не есть хорошо. Как вариант можно у фрагментов устанавливать тэг, и по нему уже узнавать какого типа фрагмент.

Ответ 5



Можно так: if (fragment instanceof ArtistFragment) { //some actions for ArtistFragment } else if (fragment instanceof AlbumFragment) { //some actions for AlbumFragment } else if (fragment instanceof SongFragment ) { //some actions for SongFragment }

Как часто стоит просчитывать путь от мобов к игроку? Поделитесь идеями

#javascript #разработка_игр



  http://smartcook.info/testgame/test2.html


Поиск пути осуществляется через алгоритм А*
Представьте есть персонаж который бегает по плоскости, вот все эти мобики должны
искать его или другие возможные цели, как часто стоит просчитывать путь к игроку, потому
как ресурсозатратно.
Поделитесь идеями как стоит строить путь к игроку. 
    


Ответы

Ответ 1



Когда-то писал игру вроде пакмана, поделюсь соображениями. Максимальная частота пересчета ограничена тем, насколько часто мобы могут поворачивать. Насколько я понимаю, пока они идут из одной клетки в другую, смена марштута невозможна. Значит, пересчитывать путь нужно не чаще, чем тогда, когда моб полностью пришел в клетку, т.е. находится в её центре. Максимальная частота также ограничена производительностью устройства, как верно отметил php5engineer в соседнем ответе. Минимальная частота пересчета задает «агрессивность» мобов и определяет геймплей. Это может быть, например: На каждой клетке — очень злой преследователь На каждой 10й клетке — довольно-таки инертный преследователь, как бык в корриде. На каждой 5й и только если персонаж игрока находится в радиусе R клеток. Раз в 2 секунды вне зависимости от скорости моба

Ответ 2



как часто стоит просчитывать путь к игроку, потому как ресурсозатратно До полного исчерпания этих ресурсов? Или до определенного процента. Например, не более 70% CPU. Или по времени - не более 1/24 секунды. Но это всё общие советы. Как это делается на JavaScript, описано здесь

Ответ 3



Лови две сносные идеи: 1) Если поле небольшое, стенки во время игры не создаются и мобы респаунятся в одной точке можно вообще всего 1 раз при загрузке просчитать путь в каждую точку поля. Тогда в худшем случае придется искать маленький путь до следующего пути в списке. 2) Можно гонять их по графу из вейпоинтов тем же А*, а А* для реального поля просчитывать только если расстояние до игрока критически уменьшилось.

Не идёт поиск если искомая строка начинается с не входящих в регексп

#javascript #регулярные_выражения #exec


Здравствуйте!

Моя задача состоит в поиске 2х групп в строке:


+
последовательность # и 0




var regex = /(\+?)((?:#*\s?)*(?:0*\s?)*(?:[.,])?(?:0*\s?)*(?:#*\s?)*)/;

var goodStr = '+#####0.00#######)';
var badStr = '(+#####0.00#######)';

console.log(regex.exec(goodStr));
console.log(regex.exec(badStr));




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

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

Заметил, что такая ситуция лишь при использовании группировки.
    


Ответы

Ответ 1



Пустая строка подходит под твою регулярку, поэтому она и выбирается. Поиск делается с самого левого из вхождений. Самое левое - это пустая строка в нулевой позиции - её ты и получаешь. Рекомендую как-то переделать регулярку, чтобы пустая строка не являлась корректным вариантом.

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

#java #android


Добрый вечер!
Каким образом реализовать вывод списка статей? Приложение получает JSON ответ от
сервера вида:

{"id":1,"message":"Тут статейка","rating":"0"}
{"id":2,"message":"Тут статейка 2","rating":"0"}
{"id":3,"message":"Тут статейка 3","rating":"0"}


Всего статей в базе около 500шт. 
Мне нужно чтобы на страницу в приложении выводились 10 статей, при нажатии кнопки,
эти 10 статей заменялись следующими 10-тью, и так далее.

Я думая для этого использовать ListView, но не совсем понимаю как заменять статьи
при нажатии кнопки, ведь чтобы загрузить следующие 10 статей, приложение должно получить
ответ от сервера с id следующих 10-ти статей. 

Прошу помочь идеей реализации подобного. Или может каким нибудь другим способом это
сделать.

P.S. Я не прошу код писать, а лишь идею реализации подобного!
    


Ответы

Ответ 1



Кроме текста статей обычно в json есть и названия. Их и показывают в списке. А сами тексты в другой Activity. ListView уже немного устарел. Вместо него сейчас используют RecyclerView. Следующая партия материалов обычно загружается, когда последний из имеющихся элементов списка появляется в области видимости. Новые элементы при этом не заменяют старые, а добавляются в конец списка.

delete [] и перемещения

#cpp #language_lawyer


int* a = new int[4];
++a;
--a;
delete [] a;


Будет валидным такой код?

А вот такой:

int* a = new int[4];
++a;
delete [] a;


Необходимо просто что бы какой нибудь указатель указывал на начало динамического
выделенного массива? И как распознается длинна массива которую нужно уничтожить? 

Может быть по типу? Но указатель указывает только на первый элемент в массиве, int*,
а не ( * a)[4]. И как можно привести во втором коде int* к (*a)[4]? Почему нет неявного
приведения?
    


Ответы

Ответ 1



Данный фрагмент кода совершенно корректный, так как оператор delete использует значение, хранящееся в указателе, которое равно значению, ранее полученному с использованием оператора new. int* a = new int[4]; ++a; --a; delete [] a; Для оператора совершенно неважно, какое до этого в указателе было значение, и как оно изменялось. Чтобы это сделать еще более наглядным то вы можете написать, например, int x; int *px = &x; int* a = new int[4]; px = a; a = &x; delete [] px; Однако данный фрагмент кода int* a = new int[4]; ++a; delete [] a; некорректный, так как указатель a не содержит адрес выделенной динамически памяти. delete и free должны применятся к значению указателя полученому по new или malloc: это требование стандарта. Обычно "под капотом" оператора new делается следующее. К запрашиваемому размеру памяти, который вы хотите выделить, добавляется к началу блока префикс, который будет хранить этот размер блока памяти. И адрес этого префикса просто вычисляется как смещение на размер слова (обычно sizeof( int) ) от начала участка памяти, адрес которой возвращается пользователю оператора new. Это значение используется, чтобы при удалении памяти правильно оценить ее размер. Что касается вашего второго вопроса, то вы можете написать, например, int* a = new int[4]; int ( *p )[4] = reinterpret_cast( a );

Ограничение на установку android-приложения

#android_sdk #android


Имеются следующие вопросы:
1. Можно ли как-то ограничить установку на, например, телефоны с API ниже 15?
Вопрос заключается не в том, чтобы запретить вывод в поиске по Маркету, а именно
запрет на установку. То есть, имея установочный файл, user не сможет установить его
из-за низкой версии.
2. Можно ли ограничить установку по разрешению экрана? Например, пользователям с
mdpi  и ldpi запретить установку уже имеющегося apk-файла? 
    


Ответы

Ответ 1



Да, можно. Для ограничения по уровню API в манифесте есть тег uses-sdk с атрибутом android:minSdkVersion (документация) Для ограничения по разрешению экрана (документация): ... ...

ignoring option MaxPermSize=512m при запуске Scala

#java #jvm #scala


Установил Play фрэймворк, и при запуске проекта выдается ошибка:


  Java HotSpot(TM) 64-Bit Server VM warning:
  ignoring option MaxPermSize=512m; support was removed in 8.0


Как исправить?


  [error]Server access Error: Connection timed out: connect url=http://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/com.typesafe.sbt/sbt-native-packager/scala_2.10/sbt_0.13/0.6.4/ivys/ivy.xml


Я так понял, он пытается что-то скачать, но доступа нет из-за этой ошибки?

ОС: Windows 8
Версия Play: play-2.2.6
Версия Java: 1.8.

Нельзя ли по-другому это обойти?
    


Ответы

Ответ 1



Первое - это не ошибка, а предупреждение. Второе. Установить прокси в браузере недостаточно, его нужно установить на уровне операционной системы. Вы не указали какую используете ОС и версию Play, поэтому могу предложить воспользоваться общим решением через activator. Запустите его так: activator -Dhttp.proxyHost="your proxyname" -Dhttp.proxyPort="your port" -Dhttps.proxyHost="your proxyname" -Dhttps.proxyPort="your port" Дополнительно может потребоваться установить параметры proxyUser и proxyPassword Обновление Для Windows 8 и Play 2.2.6 можно решить проблему воспользовавшись этой инструкцией в документации, а именно: Еслы вы находитесь за прокси, убедитеcь что установлено для Windows set HTTP_PROXY=http://<логин>:<пароль>@<хост>:<порт> От себя отмечу, что логин и пароль может и не нужен, если прокси его не требует.

Ответ 2



Вы можете попробовать установить offline := true в файле build.sbt. Во многих случаях так работает.

Ответ 3



Все просто, хоть я и сам потратил какое-то время на решение этой задачи: 1-перейти в каталог cd opt/glassfish4/bin/ 2-запустить с ROOT правами sudo ./asadmin start-domain 3-остановка сервера тоже с ROOT правами sudo ./asadmin stop-domain В вашем случае все должно заработать.

Не обновляется ListView

#c_sharp #wpf


Есть ObservableCollection, и есть ListView, который бандит элементы из
этой самой коллекции. Дальше, есть метод, в котором происходит следующая штука:

Resistances = new ObservableCollection(newList);


где Resistances - это объект ObservableCollection, связанный с ListView.
Так вот проблема: ListView не хочет обновляться после этого, хотя, вроди-как, произошла
замена коллекции и ListView должен был бы перерисоваться.

P.S. Вот так, например, работает. ListView корректно обновляется:

Resistances.Clear();
foreach (Quantity q in newList)
{
    Resistances.Add(q);
}


Так почему же не работает первый вариант - при замене всего списка? Разве не происходит
событие CollectionChanged?
    


Ответы

Ответ 1



Вероятно, ваше свойство Resistances не бросает событие PropertyChanged. Для того, чтобы обновление данных сработало нужно, чтобы ваше свойство выглядело примерно так: public ObservableCollection Items { get { return _items; } set { if (_items != value) { _items = value; OnPropertyChanged("Items"); } } } private ObservableCollection _items; XAML: UPDATE Да, вы верно поняли. У Вас получается примерно следующее: Вы создаете свойство-коллекцю и привязываете его к ListView Вы создаете новую коллекцию и присваиваете ее свойству, однако привязка не обновляется, т.к. формально ваше свойство не изменилось (не было брошено PropertyChanged). Я предпочитаю использовать ленивую инициализацию коллекций без setter'ов (возможно, вам такой подход будет интересен): public ObservableCollection Items { get { return _items ?? (_items = new ObservableCollection()); } } private ObservableCollection _items; А потом очищать и заполнять ее данными.

Ответ 2



ListView не знает о том, что коллекция заменена. Нужно вызвать OnPropertyChanged('Resistances') или другой способ дернуть событие PropertyChanged.

Delphi XE2: «Лишние» строки в исполняемом файле

#delphi #exe #delphi_xe2 #executable


Скомпилировал программу в режиме Release. Вся отладочная информация при компиляции
отключена.
Запустил программу, открыл ее свойства в Process Explorer
На закладке Strings вижу, что Process Explorer нашел много строк, которые являются
названиями модулей Delphi, названиями классов, названиями процедур и функций.

Подскажите пожалуйста, как можно удалить из релизного exe-шника все лишние данные???
    


Ответы

Ответ 1



1) В dpr файле между ключевым словом program и разделом uses напишите: program XXX; {$WEAKLINKRTTI ON} // если вам не нужны новые возможности RTTI! {$RTTI EXPLICIT METHODS([]) FIELDS([]) PROPERTIES([])} // если вам не нужны новые возможности RTTI! uses ... 2) В dpr файле после раздела uses можно еще добавить: {$IFNDEF DEBUG} {$SetPEFlags IMAGE_FILE_RELOCS_STRIPPED} // Удаление из exe таблицы релокаций. {$SetPEFlags IMAGE_FILE_DEBUG_STRIPPED} // Удаление из ехе Debug информации {$SetPEFlags IMAGE_FILE_LINE_NUMS_STRIPPED} // Удаление из exe информации о номерах строк {$SetPEFlags IMAGE_FILE_LOCAL_SYMS_STRIPPED} // Удаление local symbols {$SetPEFlags IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP} //При запуске exe с компакта, флэшки, других извлекаемых устройств, считать exe в свап и запустить оттуда. Полезно, если нужно запустить программу с компакта, а потом попросить вставить другой... {$SetPEFlags IMAGE_FILE_NET_RUN_FROM_SWAP} // Аналогично предыдущей, только для сетевых дисков {$ENDIF} При этом в uses должен присутствовать модуль Windows. Это значительно уменьшит размер исполняемого файла и уберет "лишнюю" информацию из него.

Ответ 2



Сомневаюсь, что эти данные лишние. Delphi при сборке обычно прикомпилирует некоторые "свои" модули к программе. Это можно отключить в настройках компилятора. Но, тогда придётся всегда "таскать" с программой все необходимые компоненты в виде .bpl включая те же кнопки и т.д. (смотря какие модули отключите) Вообще, релиз - это максимум что может дать компилятор. Большей экономии размера можно достичь, например, как уже говорилось, вынеся всё из экзешника ("таская" .bpl) или отказавшись от VCL (FireMonkey) в пользу чистого WinAPI (если это действительно оправдано).

Как сохранить архив с acl ntfs из под linux?

#linux #windows #файлы #ntfs #archive


Как скопировать файл/папку на разделе ntfs в архив с сохранением всех атрибутов?

При условии, что раздел смонтирован из-под linux. Аналог tar -cvf --same-permissions.

С разделами проблем нет - нужно копировать именно отдельные папки и файлы.
    


Ответы

Ответ 1



Это невозможно, так как драйвер NTFS под Linux не поддерживает виндовозные ACL.

Ответ 2



ответ из комментария: Под Windows rar и 7z умеют сохранять права и альтстримы NTFS (при указании соответствующего ключа). Под linux же этот функционал, естественно, вырезан за ненадобностью. Возможно, в самбе есть какой-то аналог ключей /save и /restore утилиты icacls, позволяющей сохранять/восстанавливать ntfs-атрибуты в отдельный файл - тогда архивировать вместе с правами не будет проблемой.

Определение координат мыши в canvas

#javascript #html #canvas


Как определить значения x, y при нажатии мыши на ? И чтобы эти значения были
у переменой сразу.



var example = document.getElementById("example"),
        ctx = example.getContext('2d');
example.width = 300; //высота
example.height = 300; //ширина
for (x = 0; x < 300; x += 100) { //поле крестиков ноликов
    for (y = 0; y < 300; y += 100) {
        ctx.strokeRect(x, y, 100, 100);
    }
}
pic = new Image();
pic.src = "нолик.png";
//pic.onload = function() {
    //example.onmouseup = ctx.drawImage(pic, 101, 1);
//}
//нужна функция
Обновите браузер



    


Ответы

Ответ 1



example.addEventListener('mouseup', function (e) { var x = e.pageX - e.target.offsetLeft, y = e.pageY - e.target.offsetTop; ⁄⁄....... });

Ответ 2



Решением из принятого ответа следует пользоваться с осторожностью, если масштаб элемента (css zoom не работает в последних firefox) не 100%, то положение мыши относительно логических пикселей в canvas сбивается, точнее так же масштабируется, как и элемент: [...document.querySelectorAll('canvas')].forEach(canvas => { var ctx = canvas.getContext('2d'); canvas.addEventListener('mousemove', function (e) { var x = e.pageX - e.target.offsetLeft, y = e.pageY - e.target.offsetTop; ctx.clearRect(0,0,100,100); ctx.beginPath(); ctx.arc(x,y,5,0,Math.PI*2,true); ctx.stroke(); }); }); canvas { border: 1px solid black; } Бороться с этим можно вот так: let z = window.getComputedStyle(canvas).zoom; var x = e.pageX/z - e.target.offsetLeft, y = e.pageY/z - e.target.offsetTop; [...document.querySelectorAll('canvas')].forEach(canvas => { var ctx = canvas.getContext('2d'); canvas.addEventListener('mousemove', function (e) { let z = window.getComputedStyle(canvas).zoom || 1; var x = e.pageX/z - e.target.offsetLeft, y = e.pageY/z - e.target.offsetTop; ctx.clearRect(0,0,100,100); ctx.beginPath(); ctx.arc(x,y,5,0,Math.PI*2,true); ctx.stroke(); }); }); canvas { border: 1px solid black; }

JpaRepository + Hibernate + OneToMany вылетает LazyInitializationException

#java #spring #hibernate #jpa #spring_data


реализую отношение one-to-many по этому туториалу а также этому спринговому туториалу.
Я НЕ использую сессии и прочий hibernate напрямую, я использую JpaRepository и аннотации
JPA. Есть объекты Owner (one) & Book (many):

первая таблица:

@Entity
@Table(name = "owners")
public class Owner implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "owner_id", nullable = false, unique = true)
    private Long id;

    @Column(name = "owner_name", nullable = false)
    private String name;

    @OneToMany(fetch = FetchType.LAZY,mappedBy = "owner")
    private Set books= new HashSet<>(0);

    public Worker() {
    }
}


вторая таблица: 

@Entity
@Table(name = "books")
public class Book implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "book_id", unique = true, nullable = false)
    private Long id;

    @Column(name = "book_name", nullable = false, unique = true)
    private String name;


    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "owner_id")
    private Owner owner;

    public Task() {
    }
}


слой репозиториев стандартный, без реализации:

public  interface OwnerRepository extends JpaRepository {}

public  interface BookRepository extends JpaRepository {}


Owner service: (book service такой же)

@Service
@Transactional
public class OwnerServiceImpl implements OwnerService {

    @Autowired
    private OwnerRepository ownerRepository;

    @Override
    public Owner create(Owner owner) {return ownerRepository.save(owner);}

    @Override
    public Owner read(Long id) {return ownerRepository.findOne(id);}

    @Override
    public List readAll() {return ownerRepository.findAll();}

    @Override
    public void delete(Owner owner) {ownerRepository.delete(owner);}

}


Создав два класса service, я захотел протестить их. Создал несколько Owner,Book ну
и пытаюсь связать их как указано здесь, т.е. добавляю в объектe Owner в Set новую книжку,
а в объект Book обновляю ссылку на Owner. Сохраняю в репозиторий сначала Owner, затем
Book. Затем пытаюсь прочитать Owner из репозитория, а во время обращения к полю выдаёт 


  unable to evaluate the expression Method threw 'org.hibernate.LazyInitializationException'
exception.


может я вообще неправильно работаю с репозиторием и JPA? как нужно сохранять/обновлять
ссылки в сущностях?

===UPDATE===

мне кажется я решил проблему, использовав @NamedEntityGraph & @EntityGraph.
Я аннотировал Owner 

@NamedEntityGraph(name = "Owner.books",
    attributeNodes = @NamedAttributeNode("books"))


Но в интерфейсе репозитория пришлось переопределить стандартные методы:

@Override
@EntityGraph(value = "Owner.books", type = EntityGraph.EntityGraphType.LOAD)
List findAll();


@Override
@EntityGraph(value = "Owner.books", type = EntityGraph.EntityGraphType.LOAD)
OwnerfindOne(Long aLong);


Тоже самое сделал с Book. Когда я делаю запрос из репозитория Owner на считывание
объекта, всё загружается нормально - ссылки в Set ссылаются на объекты Book. 
Но когда я делаю запрос к Book репозиторию - объект Book имеет ссылку на Owner, НО
в этом внутреннем Owner ссылки на дополнительные книги бросают LazyInitException. Почему?
ссылки просматриваю в Idea на брек поинте.
    


Ответы

Ответ 1



У вас стоит fetch = FetchType.LAZY это значит, что хибернейт не будет инициализировать эти поля пока вы к ним не обратитесь. Но т.к. вы обращаетесь к этим полям за пределами транзакционных методов, он не может это сделать и выкидывает ошибку. Чтобы этого избежать надо, что метод, который обращается к этим полям был с аннотацей Transactional. В вашем случае это EntitiesServicesTest.ooops(). Либо можно немного изменить реализацию OwnerServiceImpl.read(). Сделать такое: @Override public Owner read(Long id) { Owner owner = ownerRepository.findOne(id); owner.getBooks().iterator(); return owner; } Или как предложили в комментариях: Hibernate.initialize(owner.getBooks()); Это хак, но он заставит хибернейт инициировать коллекцию. НО! Возможно это не всегда надо и тогда надо выбрать первый вариант и отталкиваться от здравого смысла, смотреть, где надо навешивать аннотацию, а где нет.

Ответ 2



Стоит также упомянуть, что fetch type по дефолту как раз LAZY. Я для решения проблемы поставил fetch = FetchType.EAGER и всё заработало.

IDEA сгенерировала equals помогите разобраться

#java #intellij_idea


IDEA сгенерировала код, мог бы кто-то построчно его прокомментировать. Не понимаю,
как он работает. 

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Pair pair = (Pair) o;

    if (first != null ? !first.equals(pair.first) : pair.first != null) return false;
    return !(second != null ? !second.equals(pair.second) : pair.second != null);

}

    


Ответы

Ответ 1



@Override public boolean equals(Object o) { //Если объект, с которым происходит сравнение, этим же объектом и является, то они равны. Сравнивает ссылки текущего объекта и принятого как аргумент. if (this == o) return true; //Если принятый объект null или другого класса, то возвращает false, не равны. При o == null они не равны, т.к. у null не может быть метода equals. Следовательно основной объект не null. if (o == null || getClass() != o.getClass()) return false; //кастует 'o' в Pair pair, чтобы иметь доступ к методам. Pair pair = (Pair) o; //Проверяет что свойство first текущего объекта не равен null. Если не равен, то сравнивает first текущего объекта, с pair.first. В случае, если они не равны, то ! инвертирует в true и условие if выполняется. Выполнится return false. Объекты не равны. //Если first равен null, то проверяет pair.first. Если pair.first не равен null, то объекты не равны, возвращает false. if (first != null ? !first.equals(pair.first) : pair.first != null) return false; //Проверяет, что second не равен null. //Если не равен, то сравнивает second с pair.second. //Если second == pair.second, то сначала первый ! в "!second.equals(pair.second)" инвертирует его в его в false, а второй !, который идет сразу после return, инвертирует в true. Значит вернет true, объекты равны. //Если second == null, то проверяет второе условие. Если pair.second != null, то вернет true, который инвертируется в false. return !(second != null ? !second.equals(pair.second) : pair.second != null); } В общем, почитайте про тернарный оператор ?:. Это короткий вариант if-else. Обновление В Java все, кроме примитивов (int, char и т.п.), является объектом и наследуется от класса Object, т. е. объект любого класса можно привести к Object, будь то String, ArrayList, Integer или MyClass. На предыдущей строке идет проверка, что оба сравниваемых объекта принадлежат 1 классу getClass() != o.getClass(). Если программа проходит эту строку, значит они одного класса, соответственно имеют одинаковые свойства и методы. Для того, чтобы привести объект класса Object к другому классу, используется кастование(cast). String str = (String) object; Читайте про наследование.

как восстановить состояние после git rebase [дубликат]

#git


        
             
                
                    
                        
                            На этот вопрос уже даны ответы здесь:
                            
                        
                    
                
                        
                            Git откатить rebase [дубликат]
                                
                                    (2 ответа)
                                
                        
                                Закрыт 3 года назад.
            
                    
Предиcтория фейла:

В origin master было 10 нормальных коммитов. Понадобилось 3 коммита извлечь из истории,
а потом перенести в отдельный баранч

Вот мои действия

git checkout master
git branch test
git rebase -i HEAD~10 //удалил 3,9 и 10 коммит (условно hash: aaaaa,bbbbb,ccccc)
git push -f origin master
git checkout test
git rebase -i HEAD~10 //удалил 4,5,6,7,8 тоесть промежуточные


В это время мастер пошел вперед. Решив что пора вылить ветку test в origin, но что
бы потом сливать ветку было проще решил подлить в нее мастер но ребейсом

git checkout test
git pull --rebase origin master


Расчитывал что мои три коммита просто перетянуться вверх истории, так как предок-коммит
был. Но после кучу странных конфликтов в истории отсуствует один коммит (aaaa)

Два вопроса


В чем я ошибся и почему все так сломалось?
Что делать, как востановить утерянный коммит?

    


Ответы

Ответ 1



Ответ для второго пункта: все просто git reflog, находим состояние проекта до пула (например 3 шага назад) и делаем git reset --hard HEAD@{3}. Можно так же и бранч временный создать, чтобы поразбираться.

Как в объекте типа data.frame отобрать переменные только одного типа?

#r #dataframe


Например, имеется большой массив данных >100 переменных. А мне необходимо отобрать
 лишь количественные. Как можно сделать подобное?
    


Ответы

Ответ 1



Предварительно стоит изучить структуру данных с помощью функции str(). Выполнить поставленную Вами задачу можно следующим образом: sapply(DF, is) # классы столбцов DF[, sapply(DF, is.numeric)] # все столбцы класса numeric DF[, sapply(DF, is.factor)] # все столбцы класса factor DF[, sapply(DF, is.character)] # все столбцы класса character Можно также использовать комбинацию sapply + which: DF[, which(sapply(DF, is.numeric))]. В некоторых случаях данный вариант показывает более высокую производительность. Также стоит отметить, что для числовых переменных могут применяться разные классы: integer (целые числа), double (числа с плавающей запятой) или numeric (включает в себя два предыдущих типа). Это может пригодиться, если, например, необходимо отфильтровать только столбцы, содержащие целые числа.

Ответ 2



df_numeric <- df[ , sapply(df, is.numeric)] Создание нового дата фрейма df_numeric только с количественными данными из исходного df. is.numeric проверяет столбцы на предмет того, являются ли они количественными

Правила для определения четных/нечетных с игнорированием определенных блоков

#css #html5


Имеем такую разметку:

...
...
...
...
...
...
...
...
Необходимо стилизовать классы list по принципу четности/нечетности, но игнорируя класс ignore, т.е. так:
...
...
-- нечетный
...
...
...
-- четный
...
...
-- нечетный
...
-- четный
Простые event/oddдля .list:nth-child не подходят, т.к после .ignore отсчет начинается сначала.


Ответы

Ответ 1



Альтернативный вариант, если не брать за основу классы - использовать :nth-of-type, который в принципе аналогичен :nth-child, только применяет правило дополнительно привязываясь к тегу(типу), а не всем дочерним элементам. Собственно чтобы этим воспользоваться, все игнорируемые элементы должны быть заключены в тег, отличный от основного тега для подствечиваемых элементов. Например HTML:

...

...

...

...

...

...

...
...
Стили, где у всех div.list цвет будет чередоваться независимо от их позиции в родителе: .list { background: red; } .list:nth-of-type(odd) { background: green; } Пример на JSBin

Ответ 2



на css наверное только так Fiddle .container { width: 200px; } .list, .list ~ .list ~ .list, .list ~ .list ~ .list ~ .list ~ .list, .list ~ .list ~ .list ~ .list ~ .list ~ .list ~ .list { background: #00f; } .list ~ .list, .list ~ .list ~ .list ~ .list, .list ~ .list ~ .list ~ .list ~ .list ~ .list, .list ~ .list ~ .list ~ .list ~ .list ~ .list ~ .list ~ .list{ background: #f00; }
Ignore
Odd
Ignore
Ignore.
Even
Ignore
Odd
Even


Ответ 3



С JS это можно, например, сделать следующим образом Odd-even
Ignore
Odd
Ignore
Ignore.
Even
Ignore
Odd
Even


Почему reactjs setState возвращает предыдущее значение?

#javascript #reactjs


Мне нужно изменять state по клику. У меня есть такой код:

var Component = React.createClass({
   getInitialState : function() {
      return {value : 0}
   }
   changeState : function(event) {
      this.setState({value : event.target.id}) ;
   }
   render : function() {
      Change
   }
}) ;


Но изменение срабатывает только после первого клика, первый клик я получаю 0, второй
клик, я получаю 1.

Я перечитал доку где сказано не использовать setState напрямую, поэтому я использовал
replaceState, но и он по прежнему возвращает предыдущее значение. Как с этим бороться?
    


Ответы

Ответ 1



У setState есть довольно редко упоминаемый второй параметр, который является обычной callback функцией. Вы можете отлавливать новое состояние компонента уже там this.setState({/* new state */}, callback). var Component = React.createClass({ getInitialState : function() { return {value : 0} } changeState : function(event) { this.setState({value : event.target.id}, function() { /* Получаем измененное значение state */ console.log(this.state.value); }) ; } render : function() { return Change } }) ; Либо формируем новый объект state, а только потом записываем его: var Component = React.createClass({ getInitialState : function() { return {value : 0} } changeState : function(event) { /* формируем новый state */ let nextState = Object.assign({}, this.state, { value: event.target.id }); /* получаем будущее значение state */ console.log(nextState.value); /* записываем новый state */ this.setState(newState); } render : function() { return Change } }) ; Недавно делал небольшой перевод про работу state. Возможно пригодится

Ответ 2



Судя по всему, вы столкнулись с тем, что значение this.state меняется не мгновенно после вызова this.setState(). В тоже время, такое поведение является штатным (см. документацию): setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. Есть у меня такое чувство, что вы неправильно используете состояние компонента. К сожалению, без нормального описания исходной проблемы давать какие-то советы бессмысленно.

Лучший и быстрый вариант проверить наличие текста в массиве

#java #производительность


Здравствуйте, не стану объяснять в чём смысл всего этого кода, и сразу приступлю
к проблеме.

Если bar - ArrayList, то операция завершается за 22 секунд, С LinkedList >30 сек.
Есть ли другие варианты проверять наличие значения в массиве?
Производительность для меня очень важна :)

Есть код:

    final long time = System.currentTimeMillis();
    for (int i = 0; i < 10000000; i++) {
        foo("test");
    }
    final long endTime = System.currentTimeMillis();
    System.out.println("Time: " + (endTime - time) + " ms");


Метод foo:

public static boolean foo(String s){
    /*Всякий код*/
    return bar.contains(s);
}

    


Ответы

Ответ 1



Используйте HashSet. ArrayList: 14475 ms HashSet: 43 ms Sorted ArrayList: 540 ms Код: long time = 0; ArrayList strings = new ArrayList(); Random rand = new Random(); for (int i = 0; i < 1000; i++) { strings.add(String.valueOf(rand.nextInt())); } time = System.currentTimeMillis(); for (int i = 0; i < 10000000; i++) { strings.contains("test"); } long endTime = System.currentTimeMillis(); System.out.println("ArrayList: " + (endTime - time) + " ms"); HashSet hashSet = new HashSet(strings); time = System.currentTimeMillis(); for (int i = 0; i < 10000000; i++) { hashSet.contains("test"); } endTime = System.currentTimeMillis(); System.out.println( "HashSet:" + (endTime - time) + " ms"); Collections.sort(strings); time = System.currentTimeMillis(); for (int i = 0; i < 10000000; i++) { Collections.binarySearch(strings,"test"); } endTime = System.currentTimeMillis(); System.out.println("Sorted ArrayList:" + (endTime - time) + " ms");

Как изменить размер CardView с анимацией?

#android #android_sdk #material_design #android_ui


У меня есть layout в котором есть CardView внутри которого лежит, скажем, картинка.

Я хочу увеличить высоту и ширину этой CardView вместе с анимацией так как это делают
в Material Design Guidelines

Я пробовал 2 способа:


cardView.animate().scaleX().scaleY() - этот способ изменяет размер CardView но вместе
с ним и изменяется размер всего, что внутри его даже если у содержимого выставлена
специфичная ширина и высота;
можно сделать cardView.getLayoutParams() и потом изменить height и width или можно
добавить margin - это действительно меняет размер, но непонятно как это анимировать.


Весьма странно, но я не нашел никаких стоящих рецептов в гугле.
    


Ответы

Ответ 1



Можно воспользоваться вот этим способом с gitHub-а: Создаём анимацию изменения параметров View: public class ResizeAnimation extends Animation { final int startWidth; final int targetWidth; View view; public ResizeAnimation(View view, int targetWidth) { this.view = view; this.targetWidth = targetWidth; startWidth = view.getWidth(); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { int newWidth = (int) (startWidth + (targetWidth - startWidth) * interpolatedTime); view.getLayoutParams().width = newWidth; view.requestLayout(); } @Override public void initialize(int width, int height, int parentWidth, int parentHeight) { super.initialize(width, height, parentWidth, parentHeight); } @Override public boolean willChangeBounds() { return true; } } Применяем её: ResizeAnimation resizeAnimation = new ResizeAnimation(view, targetSize); resizeAnimation.setDuration(600); view.startAnimation(resizeAnimation);

Поставить третью систему

#linux #windows #grub


Есть Windows 7 и Linix. Хочу дополнительно к ним поставить Windows 10.

Вопрос, надо ли что-то делать с grub'ом переду установкой Win10? Или можно по стандартной
схеме просто поставить Win10, затем загрузиться с LiveUSB, откуда установить и настройть
grub? Или же следует сначала откатиться от grub'а до виндового загрузчика, чтобы Win10
при установке смог его определить?

Повторю, что в итоге я хочу получить Win7 + Linux + Win10.
    


Ответы

Ответ 1



После того, как вы установите Windows 10 (не повреждая файлы других ОС) нужно будет загрузиться с Linux и выполнить boot-repair в терминале. Не зависимо от того, увидит десятка семёрку или нет (хотя по идее должна увидеть), GRUB восстановит доступ ко всем трём ОС.

Ответ 2



Я думаю что надо поставить 10, а потом с флешки запилить grub и настроить его. Мне кажется так будет лучше.

Объявление двумерного массива java

#java #массивы


Друзья, помогите, пожалуйста, с таким вопросом. Встретил такой кусок кода в Java

public String saveComputingResult(int firstNumber, int secondNumber, String operation) {
    String[][] arr = new String[2][0]; //**
    arr[0] = new String[1]; //**
    arr[1] = new String[1]; //**
    arr[0][0] = getOperation(operation);
    arr[1][0] = Integer.toString(getComputingResult(firstNumber, secondNumber, operation));
    return arr[0][0] + " - " + arr[1][0];


Кто может пояснить выделенные комментарием //** строки? Объявляется двумерный массив
типа String, имеет две строки и....0!!! столбцов. Это как? Что это означает? В Шилдте
и Эккеле таких примеров нету, есть только примеры где размер массива указывается для
первого массива, так как это обязательно, а второй [] просто остается пустым, но что
означает если там 0 внутри? 
И что означают эти строки при этом?? 

arr[0] = new String[1];
arr[1] = new String[1];

    


Ответы

Ответ 1



Объявляется массив состоящий из двух массивов нулевой длины. То есть каждый элемент массива имеет указатель на физический адрес, где хранится массив нулевой длины. При объявлении: String[][] arr = new String[2][]; каждому элементу массива присвоено значение null вместо указателя на адрес, то есть: arr[0]=null; arr[1]=null; В вашем же случае: String[][] arr = new String[2][0]; тоже самое что: String[][] arr = new String[2][]; arr[0] = new String[0]; arr[1] = new String[0]; Массивы нулевой длины объявлены и хранятся в памяти, а arr[0] и arr[1] присвоены указатели на адреса в памяти.

Ответ 2



Согласно en-SO и здравому смыслу при записи String[][] arr = new String[2][0]; мы получаем массив из 2 массивов типа String с нулевой длинной. Далее в приведённом вами коде ячейки массива заполняются новыми массивами с одной ячейкой в каждой: arr[0] = new String[1]; arr[1] = new String[1]; При этом, т.к. ячейки не инициализированы, то if(arr[1][0]==null) System.out.println("NULL!!!111one"); выведет NULL!!!111one Таким образом, при последующем присваивании ячейкам элементов массива arr других массивов ставить им длину равную 0 (или любой другой цифре) смысла, в общем, не имеет.

Неровный круг при использовании onDraw

#android




Слева рисунок это круг используя onDraw и рисовал в Canvas через drawCircle.

А справа круг который создал через drawable circle.xml.

Можно ли сделать так чтобы круг слева был таким же как справа?

Если что могу код скинуть
    


Ответы

Ответ 1



Вот так, добавить флаг к paint, с помощью которой рисуете: Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); Или так: paint.setAntiAlias(true);

Окно редактирования настроек

#c_sharp #wpf #mvvm


public class Setting
{
    public string Setting1 {get;set;}
}
public class SettinngViewModel: ViewModelBase
{
    public SettingViewModel(Setting settings)
    {
        _settings = settings;
    }

    Setting _settings {get; private set;}

    public string Setting1
    {
        get {return setting1;}
        set {setting1=value; OnPropertyChanged("Setting1")}
    }
}


собственно вопрос в следующем: есть главная форма из которой вызывается данное окно
редактирования настроек

public MainViewModel
{
    public MainViewModel()
    {
        SettingsCommand = new RelayCommand(x=>SettingsMethod());
    }

    var currentSettings = //здесь хранятся текущие настройки

    public ICommand SettingsCommand {get; private set;}

    private void SettingsMethod()
    {
        var view = new SettingsView();
        view.DataContext = new SettingsViewModel(currentSettings);
        view.Show();
    }
}


ввиду того что settings это ссылочный тип то при изменении в окне настроек изменения
сразу отражаются в главной форме, а я бы хотел что бы это было только после подтверждения(например
пользователь нажимает кнопку Применить)

помогите реализовать соответствующую команду
    


Ответы

Ответ 1



Смотрите. Если вы редактируете настройки, вы редактируете, понятно, копию настроек, а не оригинал. В WinForms это скрывалось за тем фактом, что применение изменений происходило во View, но с WPF/MVVM правильный подход такой. Рассмотрим случай, когда у вас нет VM-объекта, отвечающего за настройки, который поддерживает свои поля в актуальном состоянии. Тогда вам нужен VM-объект «редактируемые настройки» (SettingsEditorVM), который при старте считывает свои свойства из модельного объекта, но не синхронизирует их с моделью при изменениях. Он также выставляет команду «окончить редактирование», по приходу которой проверяет настройки на правильность, и если они в порядке, записывает результат в модельный объект. Для случая, когда у вас уже есть VM-объект, отвечающий за настройки (SettingsVM), который поддерживает свои поля в актуальном состоянии, вам нужно всё равно завести ещё один VM-объект «редактируемые настройки» (SettingsEditorVM), который сможет загрузить данные (например, в конструкторе) из SettingsVM, и по команде закончить редактирование. Этим можно пользоваться так: public class SettinngEditorVM : ViewModelBase { public SettinngEditorVM(SettingVM settingsVM) { FinishedEditing = new AwaitableCommand(); CancelledEditing = new AwaitableCommand(); Setting1 = settingsVM.Setting1; } string setting1; public string Setting1 { get { return setting1; } set { setting1 = value; OnPropertyChanged("Setting1"); CheckCorrectness(); } } void CheckCorrectness() { bool ok = Setting1 != null; FinishedEditing.CanExecuteInternal = ok; } public AwaitableCommand FinishEditing { get; private set; } public AwaitableCommand CancelledEditing { get; private set; } public async Task Edit() { using (var cts = new CancellationTokenSource()) { var finished = FinishEditing.TillActivation(CancellationToke.None); var cancelled = CancelledEditing.TillActivation(CancellationToke.None); var winner = await Task.WhenAny(finished, cancelled); cts.Cancel(); await winner; return winner == finished; } } } с таким вызовом: var editorVM = new SettingsEditorVM(editorVM); var task = editorVM.Edit(); var editorWindow = new EditorWindow() { DataContext = editorVM }; editorWindow.Show(); var succeeded = await task; if (succeeded) settingsVM.LoadFrom(editorVM); Заметьте, что код у SettingsEditorVM и SettingsVM практически одинаков, так что эти два класса стоит объединить в один. Вот код AwaitableCommand: class AwaitableCommand : ICommand { bool canExecute; // не придумал названия получше public bool CanExecuteInternal { get { return canExecute; } set { if (canExecute == value) return; canExecute = value; if (CanExecuteChanged != null) CanExecuteChanged(this, new EventArgs()); } } public bool CanExecute(object parameter) { return canExecute; } public event EventHandler CanExecuteChanged; public void Execute(object parameter) { foreach (var tcs in subscribers) tcs.TrySetResult(true); subscribers.Clear(); } List> subscribers = new List>(); public async Task TillActivation(CancellationToken ct) { var tcs = new TaskCompletionSource(); subscribers.Add(tcs); using (ct.Register(() => tcs.TrySetCanceled())) await tcs.Task; } }

Добавление метода к объекту через прототип

#javascript #prototype


Приведённый ниже код должен назначить объекту типа Image с помощью прототипа три
новых метода: protocol(), host() и pathname().
В браузере FireFox всё проходит нормально. Chrome выдаёт следующую ошибку:


  Uncaught TypeError: document.i1.protocol is not a function


Соответственно, и остальные функции document.i1.host и document.i1.path не выполняются.  

В чём заключается проблема, и как её решить?

function pr() {
    a = this.src.split(':');
    return a[0] + ':';
}

function ho() {
    a = this.src.split(':');
    path = a[1].split('/');
    return path[2];
}

function pa() {
    path = this.src.split('/');
    path[0] = '';
    path[2] = '';
    return path.join('/').split('///').join('/');
}

Image.prototype.protocol = pr;
Image.prototype.host = ho;
Image.prototype.pathname = pa;

document.write("
"); document.write(document.i1.src + "
"); document.write(document.i1.protocol() + "
"); document.write(document.i1.host() + "
"); document.write(document.i1.pathname() + "
");


Ответы

Ответ 1



Полученный (например, с помощью document.getElementById('img') или new Image()) имеет тип HTMLImageElement. Соответственно, добавлять новые методы нужно именно в его прототип. Пример: function log(info) { document.body.innerHTML += info + "
"; } HTMLImageElement.prototype.protocol = function() { log("Protocol is called"); }; var img = document.getElementById('img'); log("Got image: " + img.constructor.name); img.protocol(); var newImage = new Image(); log("New image: " + newImage.constructor.name); newImage.protocol();


Ответ 2



function pr() { a = this.src.split(':'); return a[0] + ':'; } function ho() { a = this.src.split(':'); path = a[1].split('/'); return path[2]; } function pa() { path = this.src.split('/'); path[0] = ''; path[2] = ''; return path.join('/').split('///').join('/'); } Image.prototype.protocol = pr; Image.prototype.host = ho; Image.prototype.pathname = pa; var out = document.getElementById("out"), i1, html; out.innerHTML = "
"; i1 = document.getElementById('i1'); html = out.innerHTML; html += "src: " + i1.src + "
"; html += "protocol: " + i1.protocol() + "
"; html += "host: " + i1.host() + "
"; html += "pathname: " + i1.pathname() + "
"; out.innerHTML = html;
Вероятно, вы несколько раз выполнили скрипт на странице, и появилось несколько элементов с именем "i1", поэтому в последующи разы нужно было бы обращаться к document.i1[0].protocol(). Лучше сделать так: document.write("
"); var i1 = document.getElementById('i1'); document.write(i1.src+"
"); document.write(i1.protocol()+"
"); ...

Ответ 3



Вот рабочий вариант. Спасибо @Regent и @Sergiks и @Grundy
При открытии страницы все работает корректно, выводиться вся необходимая информация, не зависимо от браузера. Got image: HTMLImageElement http: localhost /JavaScriptLearning/img1.jpg

Permission denied. Не пойму, в чем может быть беда

#apache #apache2 #apache24


Настройка виртуального хоста:


ServerName test.loc

ServerAdmin webmaster@test.loc
DocumentRoot /home/r/www/test.loc/web

ErrorLog /home/r/www/logs/test.loc/error.log
CustomLog /home/r/www/logs/test.loc/access.log combined


    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted





Дополнительные настройки сервера (кроме тех, что были по умолчанию):

## Файл персональных настроек веб-сервера Apache от Razzwan-a

## Чтобы устранить предупреждение при перезапуске Apache (хотя в целом на производительности
это не отразится)
ServerName test.loc

## Для того, чтобы Apache интерпретировал php и не предлагал сохранить php-файл
AddType application/x-httpd-php .php .phtml    

## Установка кодировки по умолчанию
AddDefaultCharset UTF-8

## Настройка базовой директории

    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted



Права на папку, из которой грузится сайт (/home/r/www) 777.

И все равно выдает ошибку: 

[Thu Dec 10 10:52:54.723123 2015] [core:error] [pid ****] (13)Permission denied:
[client 127.0.0.1:] AH00035: access to / denied (filesystem path '/home/r/www') because
search permissions are missing on a component of the path
[Thu Dec 10 10:52:54.792334 2015] [core:error] [pid *****] (13)Permission denied:
[client 127.0.0.1:] AH00035: access to /favicon.ico denied (filesystem path '/home/r/www')
because search permissions are missing on a component of the path, referer: http://test.loc:81/


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

Что еще можно проверить, глянуть? Уже просто нет идей.
    


Ответы

Ответ 1



filesystem path '/home/r/www') because search permissions are missing on a component of the path у какого-то из компонентов в этом пути не хватает атрибута x для пользователя, от имени которого работает у вас apache. исправить можно, например, так (на всякий случай добавляется и атрибут r — право на чтение): $ sudo chmod +rx /home /home/r /home/r/www Require all granted директива require появилась только в версии 2.4 программы apache. если у вас, как указано с помощью меток, версия 2.2, то следует использовать директиву allow. например: allow from all

Запуск приложения с помощью java

#java


Как с помощью java запустить графическое приложение из Linux, тоесть получить доступ
к консоли.
    


Ответы

Ответ 1



Используйте ProcessBuilder ProcessBuilder builder = new ProcessBuilder("gedit"); Process process = builder.start(); Если у программы есть параметры, их нужно прописать через запятую ProcessBuilder builder = new ProcessBuilder("gedit","a.txt"); Process process = builder.start();

Комментарии c++

#cpp #комментарии


В классе определена операция /. Пишу x=a/*this. 

/* интепретируется как комментарий. Что делать?
    


Ответы

Ответ 1



x = a / *this; или, в Вашем стиле: x=a/ *this; А можно ещё вот так: x=a/(*this);

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

#java #android #время #счетчики


Пишу маленькое приложение на Android на Java. У меня пользователи в одном активити
проходят тест и, по завершению теста, открывается следующее активити, в которое передается
итоговая инфа по прохождению теста. Так вот, одно из полей - это потраченное время
на задание... я пробую считать время хронометром, но он в миллисекундах считает и потом
форматировать через различные проверки в формат 00:00 (02 : 34), очень костыльно получается...
Я уверен, что есть более изящное решение... 

Как это можно сделать?
    


Ответы

Ответ 1



В начале задания сохраняйте текущее время в long переменную: long startTime = System.currentTimeMillis(); После окончания получайте разницу: long totalTime = System.currentTimeMillis() - startTime; Берём класс Calendar и присваиваем ему полученное значение: Calendar cal = Calendar.getInstance(); cal.setTimeInMillis( totalTime ); Получаем минуты/секунды (без нулей в начале): int minutes = cal.get(Calendar.MINUTE); int seconds = cal.get(Calendar.SECOND); или в форматированном виде с помощью класса SimpleDateFormat SimpleDateFormat format = new SimpleDateFormat("mm:ss"); System.out.println(format.format(cal.getTime()));

Выбрать из таблицы все значения по одному разу (без повторов)

#mysql #sql


Допустим есть такая таблица:

id|name|number
1 |Igor|89172281212
2 |Petr|89274554545
3 |Andr|89172281212


Подскажите, как составить sql-код, который выведет 1 и 2 строчку, а 3 не надо, т.к.
их телефоны (с 1м) одинаковые.
    


Ответы

Ответ 1



Можно явно исключить лишние записи. Только надо определится по какому конкретно условию исключать. Вернее какая из записей с данным телефоном может быть более интересна. Например select * from Table as A where not exists(select 1 from Table as B where B.number=A.number and B.id

Ответ 2



Нужно сгруппировать выдачу по какому либо параметру (number) и указать что делать с остальными колонками (id, name) при группировке (min max count avg sum и т.п.)

Ответ 3



Вариант с подзапросом (по номеру берём минимальный id и потом по выбранным id соотв. записи): select T.* from TableName T join ( select min(id) as id from TableName group by number ) T2 on T2.id = T.id

Ответ 4



Упрощаю select * from t where id in( select min(id) from t group by number)

Как запретить datetimepicker смотреть во вчерашний день

#c_sharp #winforms


Как запретить устанавливать дату раньше текущей в datetimepicker?
    


Ответы

Ответ 1



Поставь свойство DateTimePicker.MinDate на текущую дату.

Как достучаться до свойств атрибута?

#c_sharp


У меня есть Type атрибута. Я разбираю Assembly по типам, которые имеют нужный атрибут.

types = ass.GetTypes().Where(t => t.CustomAttributes.Any(a => a.AttributeType ==
utilTypes[1]));


То есть получаю список типов. Мне нужно, перебирая этот список, достать свойства
атрибута. Ну например вот из этого

[MyAttribute("Hello")]
class MyClass{}


мне нужно достать свойство Prop1, которое равно "Hello". Как это сделать? Чего то
уже совсем запутался в этих рефлекциях :(

UPD1

Забыл сказать. У меня нет прямого доступа к типу атрибута. То есть я не могу сделать так

foreach (var type in types)
{
    var MyAttr = (MyAttributeAttribute)type.GetCustomAttribute(utilTypes[0].GetType())
}


Потому что этот самый тип атрибута MyAttributeAttribute я имею только в текстовом
виде. А значит мне нужно каким то образом достать из него свойство, к которому я не
имею прямой доступ
    


Ответы

Ответ 1



Попробуйте следующий подход. Пусть тип экземпляра класса MyClass лежит в переменной type. То есть: Type type = typeof(MyClass); Или в вашем случае: Type type = types[i]; Тогда следующий код: var attr = type.CustomAttributes.FirstOrDefault(a => a.AttributeType == utilTypes[0]); if (attr != null) { var attrType = attr.AttributeType; var propInfo = attrType.GetProperty("Prop1", BindingFlags.Instance | BindingFlags.Public); Console.WriteLine(propInfo.GetValue(mcType.GetCustomAttribute(attrType))); } Выведет: Hello Вот, оформил в виде метода: public static object GetAttributeProperty(Type classType, Type attributeType, string propertyName) { var propInfo = attributeType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public); return propInfo.GetValue(classType.GetCustomAttribute(attributeType)); }

Ответ 2



Воспользуйтесь функцией GetProperty у класса Type Например так foreach (var type in types) { System.Reflection.PropertyInfo propertyInfo = type.GetProperty(<Имя свойства>, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) if(propertyInfo != null) { // свойство с таким именем найдено } } Найдя свойство, из структуры System.Reflection.PropertyInfo можно получить и значение свойства, и тип... дело техники уже

Ответ 3



Как-то так: using System; using System.Linq; using System.Reflection; class Program { class MyAttributeAttribute : Attribute { public string MyProperty { get; private set; } public MyAttributeAttribute(string myProp) { MyProperty = myProp; } } [MyAttribute("Hello")] class TestClass { } static void Main() { Assembly ass = Assembly.GetExecutingAssembly(); var types = ass.GetTypes().Where(t => t.CustomAttributes.Any(a => a.AttributeType.Name == "MyAttributeAttribute")); foreach (var type in types) { var ma = type.GetCustomAttributes().FirstOrDefault((a) => { return a.GetType().Name == "MyAttributeAttribute"; }); if (ma == null) continue; var prop = ma.GetType().GetProperty("MyProperty"); if (prop == null) continue; string str = prop.GetValue(ma).ToString(); // --> Hello } } }

Ответ 4



Если параметр обязательный - то проще всего получить его значение вот так: var attr = type.CustomAttributes.Single(a => a.AttributeType.FullName == "My.Namespace.MyAttribute"); Console.WriteLine(attr.ConstructorArguments[0]);

Ответ 5



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

Выбор типа без потери точности c++

#cpp #шаблоны_с++


Есть шаблонный класс вектора:

template< int size, typename Type >
class Vector;


Есть шаблонный оператор для сложения двух векторов:

template< int size, typename LeftType, typename RightType >
Vector operator+( const Vector& left, const Vector& right )
    {...}


Который, по задумке, должен работать с любыми типами векторов, лишь бы они были одного
размера. Чтобы можно было сложить Vector<3, int> и Vector<3, double>. Но встает вопрос
- как определить результирующий тип вектора, чтобы точность не терялась?

Например для int и  double логично было бы выбрать double, для int и float - float,
для float и double - double. Как этого можно добиться, не прописывая шаблон для каждого
случая?
    


Ответы

Ответ 1



Вы можете использовать std::common_type. Ниже показана демонстрационная программа. Я объявил класс Vector с минимальными свойствами, чтобы лишь продемонстрировать использование std::common_type. #include #include #include template< int size, typename Type > struct Vector { std::vector v; }; template< int size, typename LeftType, typename RightType > Vector::type> operator +( const Vector& left, const Vector& right ) { Vector::type> v; v.v.resize( size ); for ( int i = 0; i < size; i++ ) v.v[i] = left.v[i] + right.v[i]; return v; } int main() { Vector<5, int> left = { { 1, 2, 3, 4, 5 } }; Vector<5, double> right = { { 0.1, 0.2, 0.3, 0.4, 0.5 } }; auto v = left + right; for ( int i = 0; i < 5; i++ ) std::cout << v.v[i] << ' '; std::cout << std::endl; } Ее вывод на консоль: 1.1 2.2 3.3 4.4 5.5

Ответ 2



Если есть возможность использовать C++11, то #include template< int size, typename LeftType, typename RightType > Vector() + std::declval())> ...

Не работает LIKE в SQL-запросе

#sql #sql_server


Есть DropDownlist c отступом:

Все
XXX
 XXX
  XXX
XXX
 XXX    


Запрос:

declare
@name  nvarchar(100) = ' XXX'
begin 
    SET NOCOUNT ON;
SELECT [id]
      ,[name]
  FROM dbo.test 
  where (@name = 'Все' or name Like '%'+@name+'%')
  end    


В таблице есть строка XXX без отступа.
В параметр @name передается значении с пробелами(к примеру '  XXX', ' XXX')
Как сделать чтобы оператор like работал? 
    


Ответы

Ответ 1



Если проблема в пробеле - то проще всего его обрезать: declare @name nvarchar(100) = ' XXX' begin SET NOCOUNT ON; SELECT [id] ,[name] FROM dbo.test where (@name = 'Все' or name Like '%'+RTRIM(LTRIM(@name))+'%') end

Работа с Backgroundworker и Dispatcher

#c_sharp #многопоточность #mvvm #backgroundworker


Пишу программу на C# с mvvm. У меня есть два эквивалентных куска кода, в которых,по-моему
мнению, должна происходить абсолютно одинаковая работа. Суть в чем- постепенная подгрузка(добавление)
элементов в коллекцию с помощью BackgroundWorker. Коллекция имеет биндинг с listview
 и соответственно  постепенное(пообъектное) добавление в коллекцию отображается в этом
listview.
Код:

public class ListContactViewModel : ViewModelBase
{
 public ObservableCollection DialogListFirstPage { get;set;}
 Dispatcher _dispatcher;
  public ListContactViewModel(VkApi vk)
    {  
        _dispatcher = Application.Current.Dispatcher;

       DialogListFirstPage = new ObservableCollection();
        var bw1 = new BackgroundWorker();
        bw1.DoWork += (o, e) =>
        {
            FirstDialogPageMethod(vk); //Создание коллекции диалогов

        };
        bw1.RunWorkerAsync();

 //внимания в этом методе достойна только строчка добавления в коллекцию
  private void FirstDialogPageMethod(VkApi vk)
    {
        int totalCount, unreadCount;
        var GetFirstDialigPage = vk.Messages.GetDialogs(20, 0, out totalCount, out
unreadCount);


        foreach (var i in GetFirstDialigPage)
        {

            var Names = vk.Users.Get(i.UserId.ToString(), ProfileFields.FirstName);

           _dispatcher.Invoke(()=> DialogListFirstPage.Add(new MessageChild() { AuthorFirstName
= Names.FirstName, AuthorLastName = Names.LastName, Body = i.Body, UserId = i.UserId,
Date = i.Date, ChatActiveIds = i.ChatActiveIds, Title = i.Title, UsersCount = i.UsersCount,
ChatId = i.ChatId }));

        }        
    }


на всякий случай приведу строчку биндинга из xaml:

 


И все закономерно: окно открывается пустым и я наблюдаю постоянное добавление элементов
в список.

Ситуация 2: Из предыдущего окна я перехожу в следующее , в котором аналогичная ситуация

  public class CurrentDialogViewModel:ViewModelBase
  {
   public ObservableCollection ReadyCollection { get; set; }
   Dispatcher disp;
     public CurrentDialogViewModel(VkApi vk,MessageChild parametr)
   {
       disp = Application.Current.Dispatcher;
        ReadyCollection = new ObservableCollection();
         var bw2 = new BackgroundWorker();
       bw2.DoWork += (p, m) =>
       {

           MoreMessages();

       };
       bw2.RunWorkerAsync();
 private void MoreMessages()
   {   
       foreach (var i in builder.ConcreateDialogCreater(ids))
       {
           disp.Invoke(() => ReadyCollection.Insert(0, i));

       }
       Datas.offset += 200;


   }


где builder.ConcreateDialogCreater(ids) возвращает     

 ObservableCollection 


Xaml:

   


Так вот в этом случае при открытии окна, оно у меня некоторое время остается пустым,
после чего список мгновенно отображает все объекты в ReadyCollection. 
От Insert это не зависит, с Add тоже самое. Также это не зависит от builder.ConcreateDialogCreater(ids),
потому что пробовал делать просто инициализацию объекта при добавлении в цикле

 ReadyCollection.Add(new MessageChild());


Аналогичная история-объекты вываливаются всем скопом по окончании добавления последнего.
А я хочу добиться постепенной подгрузки, как в предыдущем окне.
Почему так происходит и что нужно исправить?

UPD: 
Продебажил еще раз - все таки я был не прав и задержка связана с выполнением  метода
builder.ConcreateDialogCreater(ids). И пока он не выполнится весь- foreach не начнется.
Ведь в первом случае я коллекцию заполняю непосредственно в том классе и задержка
обоснована работой библиотечных методов перед добавлением.
Во-втором же случае нужно ждать,пока метод выполнится  полностью.
    


Ответы

Ответ 1



В DoWork вместо Dispatcher используйте ReportProgress. (для его работы надо включить WorkerReportsProgress). partial class MainWindow : Window { public MainWindow() { this.DataContext = _List = new ObservableCollection(); } ObservableCollection _List; private void Button_Click(object sender, RoutedEventArgs e) { var w = new BackgroundWorker() { WorkerReportsProgress = true }; w.DoWork += (s, we) => { for (var i = 0; i < 50; i++) { Thread.Sleep(100); // тут что-то делаем w.ReportProgress(0, i); } }; w.ProgressChanged += (s, we) => // выполняется в основном потоке _List.Add(new Message() { Text = "t" + we.UserState }); w.RunWorkerAsync(); } class Message { public string Text { get; set; } } }

Не принимает id переменная [закрыт]

#javascript #jquery


        
             
                
                    
                        
                            Закрыт. Этот вопрос не по теме. Ответы на него в данный
момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Переформулируйте вопрос,
чтобы он соответствовал тематике «Stack Overflow на русском».
                        
                        Закрыт 4 года назад.
                                                                                
           
                
        
Не принимает id переменная. 
Есть код, который при нажатии на объект(в моем случае я нажимаю на  изображения)
получает id этого объекта:

var id;
    document.querySelector('#rm').addEventListener('click', function(e){ // Вешаем
обработчик клика на UL, не LI
     id = e.target.id; // Получили ID, т.к. в e.target содержится элемент по которому
кликнули
    });


И мне нужно полученное id поместить в переменную, чтобы через нее получить адрес
изображения. Я делаю это так :

var a = document.getElementById(id);//получаю доступ к его свойствам
var canvas = document.getElementById('canvas_picker').getContext('2d');

// create an image object and get it’s source
var img = new Image();
img.src = a.src; // помещаю адрес картинки. Тут у меня и не работает!!! 

// copy the image to the canvas
$(img).load(function(){
  canvas.drawImage(img,0,0);
});


Весь код,  который при клике на любой участок  изображение можно получить код цвета
в HEX и RGB:

var canvas = document.getElementById('canvas_picker').getContext('2d');

    // create an image object and get it’s source
    var img = new Image();
    img.src = a.src; // помещаю адрес картинки. Тут у меня и не работает!!!

    // copy the image to the canvas
    $(img).load(function(){
      canvas.drawImage(img,0,0);
    });

    // http://www.javascripter.net/faq/rgbtohex.htm
    function rgbToHex(R,G,B) {return toHex(R)+toHex(G)+toHex(B)}
    function toHex(n) {
      n = parseInt(n,10);
      if (isNaN(n)) return '00';
      n = Math.max(0,Math.min(n,255));
      return '0123456789ABCDEF'.charAt((n-n%16)/16)  + '0123456789ABCDEF'.charAt(n%16);
    }
    $('#canvas_picker').click(function(event){
      // getting user coordinates
      var x = event.pageX - this.offsetLeft;
      var y = event.pageY - this.offsetTop;
      // getting image data and RGB values
      var img_data = canvas.getImageData(x, y, 1, 1).data;
      var R = img_data[0];
      var G = img_data[1];
      var B = img_data[2];  var rgb = R + ',' + G + ',' + B;
      // convert RGB to HEX
      var hex = rgbToHex(R,G,B);
      // making the color the value of the input
      $('#rgb input').val(rgb);
      $('#hex input').val('#' + hex);
    });

    


Ответы

Ответ 1



Из приведённых фрагментов кода не совсем понятно, какая часть из них находится внутри обработчика событий кликов по изображениям (или вы действительно только меняете id?). У меня ваш код работает в таком виде: var id, img, a, canvas = document.getElementById('canvas_picker').getContext('2d'); document.querySelector('#rm').addEventListener('click', function(e) { id = e.target.id; a = document.getElementById(id); img = new Image(); $(img).load(function(){ canvas.drawImage(img,0,0); }); img.src = a.src; }); https://jsfiddle.net/du5ns2ug/