Страницы

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

четверг, 18 октября 2018 г.

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

Есть массив вопросов:
String[] questions = getResources().getStringArray(R.array.questions);
Есть массив ответов на эти вопросы:
String[]answers= getResources().getStringArray(R.array.answers);
Изначально первый вопрос в массиве вопросов соответствует первому ответу в массиве ответов. В процессе игры пользователь должен ответить на вопрос и его ответ должен сравниваться с ответом из массива ответов, в результате чего либо прибавляется балл, либо нет. Ответы из массива нигде не выводятся. Отвечать на вопросы можно многократно с целью улучшения результата.
Но, чтобы исключить момент механического запоминания ответов по очередности их появления (если вопросы будут все время показывать в одном и том же порядке), вопросы перед стартом перемешиваются с помощью специального метода.
Проблема в том, как теперь указать программе, какой из ответов соответствует какому из вопросов в перемешанном массиве вопросов? Можно ли в андроид изначально связать элементы из одного массива с соответствующим им элементам из другого массива, чтобы после перемешивания первого массива, программа сохраняла связь между элементом из первого массива и элементом из второго массива?
Быть может, эту задачу может решить каким-то другим способом?


Ответ

Вам надо создать модель данных, содержащую и вопрос и ответ. После этого список этих моделей можно мешать как угодно без потери связности.
public class QAModel { String q; String a;
QAModel(String q, String a) { this.q=q; this.a=a; }
public String getQ(){return q;}
public String getA(){return a;} }
Теперь вы можете создавать вашу модель из ваших данных:
String[] questions = getResources().getStringArray(R.array.questions); String[] answers = getResources().getStringArray(R.array.answers); ArrayList models=new ArrayList<>(); for(int i = 0; i< questions.lenght; i++) { models.add(new QAModel(questions[i], answers[i])); }
Теперь вы можете сортировать вопросы, не теряя связь с ответами.

Какие “свежие” книги по C вам известны?

В университете нам твердили, что ничего лучше K&R для изучения C - нет. Сейчас студенты младших курсов интересуются, что из литературы вышло хотя бы приближенного к этой библии по C. Что можно предложить?


Ответ

Ничего лучшего, чем Керниган, Ритчи. Язык программирования C, на мой взгляд, не выходило. Причем эта маленькая книга содержит в себе помимо учебника по языку еще и учебник по хорошей практике программирования. В C не было таких революционных изменений, как в C++ - вполне можно изучить C89, а потом прочитать о внесенных изменениях (скорее - дополнениях).
Есть еще одна - более современная - хорошая книга по C: Харбисон, Стил. Язык C с примерами. М.: Бином, 2011. В ней описан в том числе и стандарт C99. Она написана больше как справочник, но может использоваться и как учебник (даже упражнения есть).
Есть еще современные книги с описанием C11:
Прата. Язык программирования C. Лекции и упражнения Дейтел, Дейтел. Как программировать на C. М.: Бином, 2014.
К сожалению ничего сказать о них не могу, т.к. сам не читал. У Дейтелов обычно хорошие книги. Только указанная книга скорее похожа на учебник по программированию, в котором за базовый язык принят C (также в ней есть и введение в C++).

Хранение одного экземпляра класса в нескольких массивах

У меня имеется класс "рассказ", который нужно хранить в различных сборниках. Суть в том, что я использую указатели, т.е.
class Story { ... }
class Compilation { ... vector stories; ... }
Необходимо изменять информацию о рассказах. Здесь всё ясно, поскольку мы храним указатели, то всё будет меняться параллельно. Удаление из конкретного сборника тоже ясно. Но если окажется, что этот сборник - последний, где хранится наш рассказ, то как произвести удаление без утечки памяти? Если же мы хотим удалить рассказ навсегда, то как его удалить из всех сборников сразу?
Хранить сборники внутри рассказа тоже не вариант, так как необходимо устраивать поиск по сборникам, количеству рассказов в них и т.д.


Ответ

Вам нужно пользоваться shared_ptr вместо сырого указателя. При этом ваш объект будет удалён только когда последний указатель на него умрёт.
Вот небольшой пример работы с ним
#include #include #include using namespace std;
class Story { int n; public: Story(int n): n(n) { cout << "story #" << n << " created" << endl; } ~Story() { cout << "story #" << n << " destroyed" << endl; } };
int main() { vector> list1, list2;
cout << "creating #1 and adding to first list" << endl; list1.emplace_back(make_shared(1)); cout << "copying #1 to second list" << endl; list2.push_back(list1[0]); cout << "creating #2" << endl; auto story2 = make_shared(2); cout << "adding #2 to the second list" << endl; list2.push_back(story2); cout << "removing first ptr to story #2" << endl; story2 = nullptr; cout << "removing second ptr to story #2, now it will be destroyed" << endl; list2.resize(1); cout << "clearing first list" << endl; list1.clear(); cout << "clearing second list, now story #1 will be destroyed" << endl; list2.clear(); cout << "done" << endl; }
Вывод:
creating #1 and adding to first list story #1 created copying #1 to second list creating #2 story #2 created adding #2 to the second list removing first ptr to story #2 removing second ptr to story #2, now it will be destroyed story #2 destroyed clearing first list clearing second list, now story #1 will be destroyed story #1 destroyed done

Как правильно подсказывает @ixSci в комментариях, вы таки можете удалить элемент полностью во всех списках, если примете немного другой дизайн. Поделим списки на владеющие своими элементами (эти списки будут содержать shared_ptr), и невладеющие (эти списки будут содержать weak_ptr, невладеющий указатель). Тогда когда все сильные ссылки (shared_ptr) на объект умрут, слабые (weak_ptr) тоже станут недействительны.
Этот оформляется так
#include #include #include #include using namespace std;
class Story { int n; public: Story(int n): n(n) { cout << "story #" << n << " created" << endl; } ~Story() { cout << "story #" << n << " destroyed" << endl; } void print() { cout << "story #" << n << " reporting" << endl; } };
int main() { vector> main_list; vector> aux_list;
cout << "creating and adding to owning list" << endl; main_list.emplace_back(make_shared(1)); main_list.emplace_back(make_shared(2)); cout << "copying to non-owning list" << endl; aux_list.push_back(main_list[0]); aux_list.push_back(main_list[1]); cout << "removing #2" << endl; main_list.resize(1); for (auto& weakptr : aux_list) { if (auto strongptr = weakptr.lock()) strongptr->print(); else cout << "(deleted entry)" << endl; } cout << "cleaning non-owning list" << endl; aux_list.erase( remove_if(begin(aux_list), end(aux_list), [](auto wp) { return wp.expired(); }), end(aux_list)); for (auto& weakptr : aux_list) { if (auto strongptr = weakptr.lock()) strongptr->print(); else cout << "(cannot happen)" << endl; } cout << "done" << endl; }
Вывод:
creating and adding to owning list story #1 created story #2 created copying to non-owning list removing #2 story #2 destroyed story #1 reporting (deleted entry) cleaning non-owning list story #1 reporting done story #1 destroyed

Как правильно парсить с помощью AngleSharp?

Всем привет! Много тем уже перечитал похожих, но в них в основном какие-то частности спрашивались. Очень согласен вот с этими словами. Ну, честно говоря, вообще ничего непонятно. Понял, что информация из html парсится либо через LINQ, либо через CSS селекторы. С первым вообще не знаком, CSS знаю поверхностно. Но все равно такой вариант мне интуитивно что ли ближе, поэтому хотелось бы ответы получить в виде CSS селекторов.
Сразу вопрос: всю ли инфу можно запарсить обоими способами? Или есть только случаи, когда работает только один из способов? Или же есть случаи, где вообще нельзя?)
Теперь непосредственно к задаче. Хочу запарсить данные контактов с сайта домофонда. Например, возьмем вот эту страницу. Парсю всю страницу для начала
var parser = new HtmlParser(); var doc = parser.Parse("ссыль");
Как, например, запарсить имя? Смотрю исходник, вижу, что имя находится в блоке div class="df_panel". Вроде бы этот блок с уникальным названием, поэтому можно сузить поиск
var div = doc.QuerySelector("div.df_panel");
Вот тут сразу начинаются вопросы. Сам разобрался, что, если в блоке div указывается название класса, то пишется так, как приведено. Если, например, div id="test", то уже запрос по-другому пишется (долго доходило на основе кучу примеров из разных форумов)
var div = doc.QuerySelector("div[id="test"");
Вот где по этому поводу что-то написано? Я так понимаю, что здесь применяются какие-то регулярные выражения. Может они аналогичные каким-то другим парсерам, как, например, написано тут, что AngleSharp очень похож на Fizzler. Но что, если у меня это локально возникшая задача, и не с какими другими парсерами я дело не имел? Как я должен понять, что именно мне писать?
Ладно, отвлекся. Див ближайший для сужения круга поиска получили. (Опять отвлекусь - кстати, а как быть, если бы его вообще не было? Можно ли каким-то образом получить определенные данные, если нет уникальных идентификаторов, посредством которых сужается постепенно зона поиска нужного значения?). Итого видим, что имя записано в тег заголовка

НУЖНОЕ ИМЯ
. Как получить это значение? Было бы возможно вытащить имя, если бы оно было записано вообще без тега заголовка?
Пока на этом вопросы задавать перестану. Буду благодарен за любые объяснения. Желательно очень получить ответы на более общие вопросы (например, по поводу, как я предполагаю, этих регулярных выражений с хелпом или хорошими примерами), тогда может с остальной частью я и сам разберусь.


Ответ

Самое важное
Перво-наперво, вам нужно выучить CSS селекторы. А для лучшего понимания, хотя бы еще основы HTML. Сделать это можно, например, на HTML Academy. Бесплатно.
Я бы еще добавил, что никакой магии нет- все выборки AngleSharp это стандартные селекторы CSS, а не что-то необычное. (c) ReinRaus
Отвечу на ваш вопрос:
Но что, если у меня это локально возникшая задача, и не с какими другими парсерами я дело не имел? Как я должен понять, что именно мне писать?
Чтобы понять, что надо писать, повторюсь, вам надо выучить CSS селекторы. Сделать это можно, например, здесь: "Знаете ли вы селекторы?".
Приведу здесь краткую выжимку из упомянутой выше статьи:
Основные виды селекторов
Основных видов селекторов всего несколько:
* – любые элементы. div – элементы с таким тегом. #id – элемент с данным id .class – элементы с таким классом. [name="value"] – селекторы на атрибут (см. далее). :visited – «псевдоклассы», остальные разные условия на элемент (см. далее).
Селекторы можно комбинировать, записывая последовательно, без пробела:
.c1.c2 – элементы одновременно с двумя классами c1 и c2 a#id.c1.c2:visited – элемент a с данным id, классами c1 и c2, и псевдоклассом visited
Отношения
В CSS3 предусмотрено четыре вида отношений между элементами.
Самые известные вы наверняка знаете:
div p – элементы p, являющиеся потомками div. div > p – только непосредственные потомки Есть и два более редких:
div ~ p – правые соседи: все p на том же уровне вложенности, которые идут после div. div + p – первый правый сосед: p на том же уровне вложенности, который идёт сразу после div (если есть).
Селекторы атрибутов
На атрибут целиком:
[attr] – атрибут установлен, [attr="val"] – атрибут равен val.
На начало атрибута:
[attr^="val"] – атрибут начинается с val, например value. [attr|="val"] – атрибут равен val или начинается с val-, например равен val-1. На содержание: [attr*="val"] – атрибут содержит подстроку val, например равен myvalue. [attr~="val"] – атрибут содержит val как одно из значений через пробел. Например: [attr~="delete"] верно для edit delete и неверно для undelete, а еще неверно для no-delete
На конец атрибута:
[attr$="val"] – атрибут заканчивается на val, например равен myval
Где попрактиковаться?
CSS Diner - здесь нужно выбирать элемент, соответствующий указанному CSS правилу. HTML Academy - здесь можно изучить основы верстки. htmlbook - справочник по css селекторам и html тегам.
Ответы на остальные вопросы
Вот где по этому поводу что-то написано? Я так понимаю, что здесь применяются какие-то регулярные выражения.
Это не регулярные выражения, а CSS селекторы. Об этом я написал выше.
Можно ли каким-то образом получить определенные данные, если нет уникальных идентификаторов, посредством которых сужается постепенно зона поиска нужного значения?
Да, комбинируя дочерние элементы по любому признаку. Например, первый потомок в родителе (* > *:first-child), точно второй по счету элемент p внутри своего родителя (p:nth-child(2)), не пустой a элементы (a:not(:empty)) и так далее.
Итого видим, что имя записано в тег заголовка

НУЖНОЕ ИМЯ
. Как получить это значение? Было бы возможно вытащить имя, если бы оно было записано вообще без тега заголовка?
Если я правильно понял, и имеется в виду значение, не обернутое в какой-либо тег, то все равно ответ будет – да. Можно выполнить поиск по тексту. Для этого конкретного случая решение в виде селектора будет таким: h6[itemprop="name"]
как только не пробовал. Не парсит с .df_panel
Ваш код из комментариев использует метод QuerySelector, который, как я понимаю, выбирает первый элемент с указанным селектором. Первый .df_panel из шести на странице не содержит элемента h6. Поэтому у вас ничего и не находит. Еще раз подчеркну: на странице шесть элементов .df_panel
Код для выборки нужного вам элемента
var seller = doc.QuerySelector("[itemprop='seller']"); var name = seller.QuerySelector("[itemprop='name']").Text();

Чем переменная класса отличается от экземпляра класса?

Например, у нас есть класс MyClass
Чем вот эта запись
MyClass class = new MyClass();
отличается от этой
MyClass class;


Ответ

MyClass myClass = new MyClass();
Вы объявляете переменную или поле myClass типа MyClass. Создаете новый экземпляр (объект) класса MyClass. Присваиваете ссылку на созданный экземпляр переменной.

MyClass myClass;
Вы объявляете переменную или поле myClass типа MyClass. Переменная не инициализирована никаким значением, работать с ней нельзя, пока вы не присвоите ей ссылку на какой-нибудь экземпляр.

Как работает код [i for i in range(51) if i % 2 == 0]?

evens_to_50 = [i for i in range(51) if i % 2 == 0] print evens_to_50
Этот код генерирует список из четных чисел до пятидесяти. Но мне, как новому в программировании непонятны некоторые моменты - :
Почему генерация происходит в квадратных скобках, их же обычно используют при работе с индексами Что делает первая i перед циклом for? Почему после range(51) нет двоеточия и перевода на новую линию с табулированием? Где еще могут использоваться квадратные скобки? В квадратных скобках можно сколько угодно if или for писать? Какие в них правила?


Ответ

Эта конструкция называется "генератор". Это способ в одну строку создать список (массив), наполненный значениями. Двоеточия нет именно потому, что это не цикл for, а генератор. Давайте разберем подробно:
[i for i in range(51) if i % 2 == 0]
или в более общем виде:
[expr(variable) for variable in iterable if condition(variable)]
Здесь:
iterable — некий объект, из которого можно один за другим получать значения (пока не кончатся). Список, кортеж или, например, ключи словаря. Отсюда поштучно берутся значения и присваиваются переменной variable. Поочередные операции называются "итерациями", а вышеописанный объект — итерируемым (iterable)
Выражение range(51) возвращает список натуральных чисел от 0 до 50 включительно. Их мы и перебираем. variable (имя произвольное) — просто переменная, поочередно принимающая все значения из iterable. Работает точно так же, как счетчик в цикле. expr(variable) — любая функция, которая возвращает значение. Она может принимать аргументом variable, может что угодно ещё, может вообще ничего не принимать. Понятно, что i возвращает просто значение i в неизменном виде. Возвращаемые этой функцией значения становятся элементами генерируемого списка. Другие примеры:
[i**2 for i in range(51)] – квадраты чисел [0 for i in range(51)] – просто заполняем нулями condition(variable) — необязательное условие. Если оно присутствует, то в полученный список войдут только те значения, для которых condition(variable) == True. Можно написать одно if, но внутри может быть сколь угодно сложное выражение, т.е. if a(i) and b(i) or c(i)...
В данном случае выбираются те числа, которые кратны двум (т.е. чётные).

Как грамотно обработать деление на ноль?

Есть унаследованный класс:
public class Division : BinaryOperation { protected override decimal Calculate(decimal a, decimal b) { return a / b; }
public override string Name { get { return "Деление"; } } }
Как внутри него красиво и логично обработать ситуацию деления на ноль? Если обернуть в try-catch, что писать в catch? Допустим, я не знаю какие контролы будут на форме, и вообще, будет ли это использоваться в WinForms или WPF или что-то еще, чтобы куда то выводить текст Exception'а. Возможно есть еще какие-то хорошие варианты кроме try-catch?


Ответ

Сложность в "элегантной" обработке исключений заключается в том, что она сильно зависит от контекста.
Вот, например, в одном приложении, нужно выделить UI контрол и попросить пользователя ввести валидное значение. В другом приложении (если оно серверное), нужно бросить исключение, которое должно пересечь границы приложения тем или иным способом. А в третьем приложении, проверка аргументов происхоидт на более высоком уровне и передача 0 в параметр b является багом и должно привести к крэшу приложения.
Все это приводит к следующим возможностям:
Добавить предусловие в метод Calculate, что b != 0: Contract.Requires(b != 0). В этом случае мы переклаыдваем ответственность за валидацию кода на вызывающую сторону. Мы говорим, что 0 - это невалидное значение, и просим клиента нас не трогать в этом случае. Ничего не делать и пробрасывать DivideByZeroException. Еще одна альтернатива: задокументировать метод Calculate и "сказать", что из него может прилететь это исключение.
В этом случае мы опять же перекладываем ответственность на вызывающий код, который лучше знает, что с ним делать. Теперь клиент может выдать сообщение, отправить нужный ответ клиенту или преобразовать это исключение в какое-то другое.
Добавить новый уровень косвенности. Еще, можно добавить специальный тип исключения, например, CalculationException или OperationException. В этом случае, новый тип исключения будет описывать семейство ошибок, которое может произойти при работе с абстрактной операцией.
Это решение является более расширяемым, поскольку новые наследники могут бросать новые и новые типы исключений, а конкретный тип исключения может содержать более специфичную информацию:
public abstract class OperationException { }
public class DivideByZeroOperationException : OperationException {}
public class Division : BinaryOperation { protected override decimal Calculate(decimal a, decimal b) { if (b == 0) {throw new DivideByZeroOperationException();}
return a / b; } }
Теперь клиент может решить, нужно ли ему обрабатывать базовое исключение или же более специфичное.
Еще одна альтернатива, вернуться к умным кодам возврата и уйти от исклчюений.
Пример:
public enum Error { DivideByZero, YetAnotherError }
// Это такой себе 'Either' тип, который может содержать либо ошибку (код и, // возможно, сообщение), либо валидный результат public class OperationResult { public decimal? Result {get;} public Error? Error {get;}
public static OperationResult Success(decimal result) { }
public static OperationResult Failure(Error error) { // Может быть стоит добавить сообщение или другую контекстную инфомрацию } }
public class Division : BinaryOperation { protected override OperationResult Calculate(decimal a, decimal b) { if (b == 0) {return OperationResult.Error(Error.DivideByZero);} return a / b; }
}
Это более "функциональный" подход, в то время, как предыдущие являются более каноническими в ОО языках, таких как C#.
Главное заключение: не существует вменяемого способа полностью обработать исключение внутри метода Calculate. Информация об ошибке должна быть передана вызывающему коду, поскольку только на более высоком уровне существует достаточно инфомрации (контекста), чтобы обработать эту проблему полноценным образом.

C++ вывод “галочки” на экран

Как вывести с помощью std::cout << ("") << std::endl; галочку на экран.


Ответ

Например так:
cout << "\u2713" <Или другие галочки по ссылке: Галочка

Как обернуть много методов?

Задача следующая. Есть некий обособленный класс Test с методом TestMethod.
public Test { public void TestMethod() { //... } }
Также есть множество других классов, которые наследуются от одного абстрактного класса и в этих классах большое количество методов. Нужно, чтобы во всех этих методах сначала вызывался TestMethod(), затем шло непосредственно тело самого метода и затем снова вызывался TestMethod(), то есть:
public Class1:AbstractClass { public void Method1() { TestMethod() //тело метода TestMethod() } public void Method2() { TestMethod() //тело метода TestMethod() }
}
Понятное дело, что можно так и прописать в каждом методе каждого класса. Но может есть более изящный способ обернуть тела методов?
(!!!) Методы могут иметь разные входные и выходные параметры. Не только void и без параметров.


Ответ

Вам нужно использовать какой-нибудь AOP-фреймворк. Вот тут есть большой их список.
Давайте сделаем пример с популярным Castle.DynamicProxy
Отмечу сразу, нам нужно будет модифицировать код. Перехватываемые методы (то есть, те методы, к которым мы «добавляем» вызов TestMethod) должны быть виртуальными. Если это — слишком большое ограничение, вам понадобится другой AOP-фреймворк (например, PostSharp).
Пусть наш код такой:
class Program { static void Main(string[] args) { var derived = new Derived(); derived.M3(); } }
class Base { public void M1() { Console.WriteLine("Base::M1"); }
public int M2(int arg) { Console.WriteLine($"Base::M2, arg = {arg}"); return arg + 1; } }
class Derived : Base { public int M3() { Console.WriteLine("Derived::M3"); return M2(10); } }
и тестовый класс
class Test { public static void TestMethod(bool entry) { Console.WriteLine($"Test::TestMethod ({(entry ? "in" : "out")})"); } }
Подключим через nuget Castle.Core, и допишем наш интерсептор:
using Castle.DynamicProxy;
public class Interceptor : IInterceptor { public void Intercept(IInvocation invocation) { Test.TestMethod(); try { invocation.Proceed(); } finally { Test.TestMethod(); } } }
Затем (ограничение Castle.Proxy) нам нужно сделать наши классы публичными, а методы виртуальными. Получаем такой изменённый код:
public class Base { public virtual void M1() { Console.WriteLine("Base::M1"); }
public virtual int M2(int arg) { Console.WriteLine($"Base::M2, arg = {arg}"); return arg + 1; } }
public class Derived : Base { public virtual int M3() { Console.WriteLine("Derived::M3"); return M2(10); } }
Меняем Main
class Program { static void Main(string[] args) { var i = new Interceptor(); var proxy = new ProxyGenerator().CreateClassProxy(i); proxy.M3(); } }
Вывод программы:
Test::TestMethod (in) Derived::M3 Test::TestMethod (in) Base::M2, arg = 10 Test::TestMethod (out) Test::TestMethod (out)

Чем отличается Comparable от Comparator?

Когда использовать Comparable, а когда Comparator?


Ответ

Классы реализуют Comparable, чтоб можно было потом сортировать за счёт реализации compareTo(Object) метода.
Если класс реализует этот интерфейс, то можно использовать потом Collection.sort() или Arrays.sort(). Объекты будут сортироваться основываясь на реализации compareTo(Object) метода.
Например:
public class Country implements Comparable{
@Override public int compareTo(Country country) { return (this.countryId < country.countryId ) ? -1: (this.countryId > country.countryId ) ? 1:0 ; } }
При вызове Collection.sort() на коллекции объектов этого класса, они будут сравниваться основываясь на compareTo(Country country)
А Comparator используется, чтоб реализовать сортировку по кастомному полю, типо:
List listOfCountries = new ArrayList(); [...] Collections.sort(listOfCountries,new Comparator() {
@Override public int compare(Country o1, Country o2) {
return o1.getCountryName().compareTo(o2.getCountryName()); } });
Будут отсортированы объекты основываясь на сравнении имён стран.
Если резюмировать, то:
Comparable - реализуется внутри класса. По сути, определяет обычный/естественный порядок сравнения объектов.
Comparator - реализуется вне класса. Можно реализовать различные варианты сортировки, основанные на сравнении различных полей.

Есть ли разница между выражениями !!( a && b ) и (a && b)?

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


Ответ

Для начала приведу немного теории.
На самом деле, в JavaScript логические операторы || и && работают особым образом.
Оператор || возвращает первый из операндов, значение которого может быть приведено к логическому true. Если же оба операнда приводятся к логическому false, то оператор || вернет последнее значение
console.log('foo' || false); // 'foo' console.log(null || 'bar'); // 'bar' console.log(false || 1); // 1 console.log(false || null); // null
Это позволяет использовать всеми любимый широко известный хак со значением переменной по умолчанию:
function f(arg) { var a = arg || 0; // ... }
Оператор && возвращает первый из операндов, значение которого приводится к логическому false. Если же оба операнда приводятся к true, то оператор && вернет последний операнд
console.log(true && []); // [] console.log(null && 'foo'); // null console.log(0 && 'foo'); // 0 console.log('foo' && 'bar'); // 'bar'
Что касается конструкции !!, то она используется для явного приведения операнда к логическому типу:
console.log(!!'foo'); // true console.log(!!''); // false console.log(!!0); // false console.log(!!1); // true

Вернемся к вашему вопросу.
Как вы уже могли догадаться, разница между выражениями
!!(a && b); // (1) (a && b); // (2)
заключается в типе возвращаемого значения. Если обе переменные a и b оба имеют логический тип, то эти выражения эквивалентны. В общем же случае, тип результата выражения (2) определяется типом операндов, тогда как выражение (1) всегда возвращает значение логического типа.

Заменить символ '/' на “\\”

Нужно в строке заменить все символы / на \\. Делал следующим образом:
string s; cin >> s; for(int i = 0; i < s.size(); i++) { if(s[i] == '/') { s.replace(i, 1, "\\"); } }
Но почему-то получается так, что символ / заменяется только на \, а не на \\


Ответ

Дело в том, что "\\" и есть одиночный бекслеш. Попробуйте "\\\\"

В C++ в строковых литералах \ является специальным экранирующим символом: он означает не себя, а просто модифицирует значение следующего за ним символа. Например,
означает не бекслеш и символ n, а перевод строки, символ с кодом 0x10.
Поэтому сам по себе бекслеш не означает бекслеш. Для ввода бекслеша нужно использовать \\
Вы можете проверить длину строки "\\\\", она равна 2. (Проверка: http://ideone.com/DhxHe8)

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

Отступы между элементами с inline-block

Откуда берутся отступы между элементами с display: inline-block и как их убрать? Отступы нигде не фиксируются:


Ответ

Дело в том, что inline-block рендерится браузером как буква. Расстояние, которое вы видите между inline-block и соседними "буквами" – обычный межбуквенный интервал или, если брать термин из типографики, трекинг.
Трекинг не является фиксированным значением и меняется в различных семействах шрифтов, а также зависит от размера шрифта. Из-за этого мы не можем использовать для решения этой проблемы фиксированные значения в свойствах word-spacing, margin и т.д.
Эффективно убрать отступы у inline-block можно несколькими способами:
Вариант 1
В разметке убираем переносы для кнопок.


Вариант 2
На родителя ставим font-size: 0; а уже к button задаем нужный размер шрифта.
main { font-size: 0; }
button { font-size: 14px; }
Вариант 3
Можно закомментировать конец и начало строки.

Спецификатор final для функции

При добавлении спецификатора final мы запрещаем переопределять метод в базовом классе. Тогда зачем нам нужен в базовом классе создавать виртуальный метод, если можно его оставить обычным? Для чего еще используется виртуальный модификатор?
class Base { public: virtual void doSomething(int x) final; };
Например вот так:
class Base { public: void doSomething(int x); };


Ответ

Такая комбинация virtual и final будет формально корректной, но фактически бессмысленной. Так что вопрос тут скорее к автору кода: зачем они объявили такой метод?
Если задаться целью попритягивать за уши оправдания для такого использования, то возможной причиной может быть желание формально сделать класс полиморфным. (Например, захотелось мне для каких-то моих целей, чтобы dynamic_cast работал с указателями типа Base *, а класс Base * как назло у меня не является полиморфным.) Для этого надо создать в нем хотя бы один виртуальный метод, даже если виртуальность этого метода на самом деле "никому больше не нужна". Традиционно в таких ситуациях виртуальным делают деструктор. Но в качестве странноватого альтернативного варианта можно рассмотреть и такую "фиктивную" виртуальность, как в вашем примере.
P.S. Не надо называть невиртуальные методы "статическими". Термин статический метод в языке С++ уже зарезервирован и используется для совсем других целей.

Можно ли предсказать максимальный размер png изображения?

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


Ответ

Вы задали сложный и интересный вопрос, точного ответа на который скорее всего ни у кого нет. Хотя Вы можете поискать какие-нибудь оценки алгоритма сжатия DEFLATE, который используется в PNG. К слову, о PNG. Это формат хранения картинок со сжатием данных без потерь, в котором используется алгоритм DEFLATE. Метод не из самых простых. Его достаточно хорошее описание мной найдено было найдено здесь, здесь, частично тут и вот тут. Но в силу того, что мои интересы лежат немного в стороне от сжатия данных, вспоминать коды Хаффмана в различных вариациях я не стал, а избрал иной, более дешёвый подход к решению задачи. Он даёт худший результат и не точный результат. Но, при должном развитии идеи, которую я опишу, можно получить достаточно качественные нижнюю и верхнюю оценки. Нужно также понимать, что используюя данный подход, всегда можно будет подобрать такое изображению, которое будет выбиваться из общей динамики картинок. В силу того, что я не знаю, что и как Вы хотите оптимизировать, приведу лишь основные положения того, что можно делать. Всё ниже перечисленное снабжу кодом на python 2.7. Готового решения, к сожалению, я не дам, посколько не знаю целей. Но на основе моих наработок можно получить очень хороший результат.
Насчёт точной оценки. Её скорее всего можно получить, изучив то, как ведут себя коды Хаффмана. Но это будет трудоёмкий процесс. Вопрос в том, насколько это Вам нужно.
Общая идея подхода состоит в том, чтобы выявить зависимость
, где
-- параметры, которые будем задавать. Указанную зависимость мы будем получать, рассматривая некоторое множество изображений (у меня на компьютере есть база со стоковыми фотографиями профессиональных фотографов). Эти изображения мы будем рассматривать как объекты. Выше указанную зависимость мы будем строить, основываясь на выборке картинок.
Если у Вас нет python и IDE для него, то я советую Вам pyCharm. Все вопросы по установке, либо возникающим проблемам Вы можете задавать в комментариях. Начиная работать, обязательно обратите внимание на pip -- установщик пакетов, который, кстати, очень хорошо интегрирован в pyCharm
Теперь насчёт изображений. В сети полно всяких дампов фоток, картинок и другого хлама. Вы легко их можете найти в гугле. Но проблема в том, что они могут быть в разных форматах. Эта проблема легко решает приведенеием их к *.png. Сделать это можно так:
import Image import glob
listOfImages = glob.glob("/home/hedgehogues/project/testPNG/*.jpg") # Получаем список имён файлов
index = 0 for itemFile in listOfImages: img = Image.open(itemFile) img.save("/home/hedgehogues/project/testPNG/" + str(index) + ".png") index += 1 print index
Код комментить не буду. Он вроде бы понятен.
Итак, начал я с того, что решил поглядеть, что представляет собой размер картинки (далее картинка -- это некоторый экземпл базы картинок) в зависимости от её площади. К сожалению, здесь меня ждал грустный ответ. Это не очень хорошое распределение. Вы можете на него взглянуть:

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

Нижняя граница соответственно:

Таким образом, размерах файлов при фиксированной площади может сильно варьироваться (практически в 3 раза) ~ 2.922. Для того, чтобы понять, что это много, можно сравнить 3 Мб и 9 Мб. 300 кБ и 1Мб. Разница ощутима. Апогея она достигнет, если рассматривать изображения очень больших размеров: 50 Мб и 150 Мб. Каково?
Я приведу код, с помощью которого можно произвести рассчёты:
import Image import os import matplotlib.pyplot as plt import numpy as np
listOfSize = [] # Размер файла total = [] # Площадь картинки
index = 0 for itemFile in range(0, 260): tmpSize = os.path.getsize("/home/hedgehogues/project/testPNG/" + str(index) + ".png") # Получаем размеры файла с картинкой img = Image.open("/home/hedgehogues/project/testPNG/" + str(index) + ".png") hLocal, wLocal = img.size # Размеры сторон картинки img = np.array(img.convert('L')) listOfSize.append(tmpSize) total.append(wLocal * hLocal) index += 1 print index
plt.plot(total, listOfSize, linestyle = '', marker = 'x') plt.show()
Следующим логичным шагом стало предположение о том, что, информация о длинах сторон картинок -- это совсем неинформативный признак, поскольку внутри каждой картинки кроется различная информация, а следовательно, самые информативные параметры будут связаны с интенсивностями пикселей. Здесь я оговорюсь, что далее, для простоты, все изображения я буду приводить к градациям серого. Разумеется, если этого не делать, а работать со всей информацией, то мы получим более качественные результаты. Но и сложность задачи возрастает в разы.
Для учёта этой информации будем строить гистограммы изображений:

Но, вот незадача, мои изображения оказываются очень большими (5000х5000) и их обработка занимает порядочное время. Поэтому я их жму. Получаю:

Как видим, характер гистограммы сохраняется. Приведу код, который позволяет построить такого класса гистограммы:
import Image import matplotlib.pyplot as plt import numpy as np
index = 0 for itemFile in range(0, 250): img = Image.open("/home/hedgehogues/project/testPNG/" + str(index) + ".png") img.thumbnail((300, 300), Image.ANTIALIAS) # сжатие изображения img = np.array(img.convert('L')) y = np.histogram(img, bins = range(0, 256)) # bins задачёт количество градаций гистограммы x = np.arange(0, 1, 1./255) plt.plot(x, y[0]) plt.show() index += 1

print index
Что со всем этим делать? Легко. Можно построить аппроксимацию этих гистограмм. Это можно делать по-разному. Например, при помощи нелинейного МНК. Я подобрал такую функцию, которая более или менее отвечает гистограммам. Все гистограммы для МНК нормируются по отрезку [0; 1]. Вот, что мы получаем. Несколько гистограмм и построенных для них МНК:

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

Средствами python легко найдём неизвестные параметры, если минимизировать будем функцию, которая соответствует МНК:

Для минимизации перебёрем все данные для каждой гистограммы. Все эти действия можно проделать самостоятельно:
import Image import scipy.optimize as opt import matplotlib.pyplot as plt import numpy as np
# Целевая функция def Model(a, x): sum = a[0] for coeff in range(1, len(a)): sum += a[coeff] * ((x * np.sin(x)) ** coeff + np.exp(x)) return sum

index = 0 for itemFile in range(0, 250): img = Image.open("/home/hedgehogues/project/testPNG/" + str(index) + ".png") img.thumbnail((300, 300), Image.ANTIALIAS) img = np.array(img.convert('L')) weight = np.array(range(0, 10)) ErrorFunc = lambda tpl, x, y: 0.5 * (Model(tpl, x) - y) ** 2 # Функционал минимизации y = np.histogram(img, bins = range(0, 256)) x = np.arange(0, 1, 1./255) # Нормировка y = y[0] / float(np.max(y[0])) # Нормировка spl = opt.leastsq(ErrorFunc, weight, args = (x, y)) # Вычисление коэффициентов yy = Model(spl[0], x) plt.plot(x, yy) plt.plot(x, y) plt.show() index += 1

print index
Получим веса w_i, а также имея площадь, можем построить ещё одно регрессионную модель, которая будет предсказывать размер конкртеного изображения. Сделать это можно по аналогии с тем, как построена регриссионная модель выше. Введём некоторую целевую функцию и функционал минимизации. Запишем исходные данные в виде: u_i = [w_i, area]. Теперь имея в качестве исходных данных пары (u_i, total_size), аналогичным образом обучим модель и получим некоторую зависимость. По указанной зависимости можно будет предсказывать предполагаемый размер файла.
С другой стороны, можно воспользоваться более простой идеей и также, как и ранее, получить верхнюю и нижнюю оценку. Для этого посчитаем среднее значение элементов гистограммы. Построим график зависимости размера файла от среднего значения:

Предвосхищая вопросы. Замечу, что на графике присутствуют два вида точек. Синие -- это множество, на котором производилось "обучение". Красные -- это точки, взятые из интернетов (картинки скачал). Как видим, они примерно укладываются в общую тенденцию. Разумеется, в данной ситуации у нас есть выбросы, которые нужно отдельно обработать и понять их причину. Кроме того, наша оценка средним значением гистограммы очень груба. А значит не следует претендовать на слишком качествеенный результат. Также отмечу, что построение гистограммы для отдельного изображения -- это затратная операция. Поэтому имеет смысл брать некотору аппроксимацию этой операции (например, брать на изображении случайные пиксели и строить гистограмму по ним).
Приведу код:
import Image import os import matplotlib.pyplot as plt import numpy as np

def Model(a, x): sum = a[0] for coeff in range(1, len(a)): sum += a[coeff] * ((x * np.sin(x)) ** coeff + np.exp(x)) return sum
listOfSize = [] listOfSizeTest = [] h = [] w = [] total = [] totalTest = [] data = []
# Перебираем все элементы из train set index = 0 for itemFile in range(0, 250): img = Image.open("/home/hedgehogues/project/testPNG/" + str(index) + ".png") img.thumbnail((300, 300), Image.ANTIALIAS) img.save("/home/hedgehogues/project/testPNG/_-1.png") tmpSize = os.path.getsize("/home/hedgehogues/project/testPNG/_-1.png") img = np.array(img.convert('L')) y = np.histogram(img, bins = range(0, 256)) total.append(np.mean(y[0] / float(np.max(y[0])))) index += 1

print index
# Перебираем все элементы из test set (картинки из интернетов) for itemFile in range(0, 6):
img = Image.open("/home/hedgehogues/project/testPNG/_" + str(itemFile) + ".png") img.thumbnail((300, 300), Image.ANTIALIAS) img.save("/home/hedgehogues/project/testPNG/_-1.png") tmpSize = os.path.getsize("/home/hedgehogues/project/testPNG/_-1.png") img = np.array(img.convert('L')) listOfSizeTest.append(tmpSize) y = np.histogram(img, bins = range(0, 256)) totalTest.append(np.mean(y[0] / float(np.max(y[0]))))
plt.plot(total, listOfSize, linestyle = '', marker = 'x') plt.plot(totalTest, listOfSizeTest, linestyle = '', marker = 'x', color = 'red') plt.show()

Время выполнения функций

Вот, я создал constexpr функцию. Как точно определить, выполнится она во время компиляции или в runtime?


Ответ

Присвойте ее значение переменной, объявленной как constexpr. Если все пройдет успешно - значит, выполнилось во время компиляции :)

Как сгенерировать звуковой сигнал синусоиду с изменяющейся частотой?

Задача научиться генерировать сигналы для вывода на наушник или динамик (под Андроид). Синусоида, пила. прямоугольник, но с изменением во времени.
Например синусоида у которой частота меняется от 500Гц до 1000Гц в течении 60 секунд. Где об этом можно почитать или кто поделится личным опытом работы с этим.


Ответ

Генерируем синусоиду с переменной частотой:
private static byte[] generateSineWavefreq(int startFreq, int endFreq, int seconds) { int sampleRate=44100; //частота дискретизации - можно взять даже 8000 double freq, angle; byte[] sin = new byte[seconds * sampleRate]; for (int i = 0; i < sin.length; i++) { freq=startFreq+(endFreq-startFreq)*1.0/sin.length*i; angle = (2.0 * Math.PI * i)*freq/sampleRate; sin[i] = (byte) (Math.sin(angle) * 127); } return sin;
}
Проигрываем полученную волну:
final AudioFormat af = new AudioFormat(sampleRate, 16, 1, true, true); try { SourceDataLine line = AudioSystem.getSourceDataLine(af); line.open(af); line.start(); play(line, generateSineWavefreq(5000, 1000, 1)); line.drain(); line.close(); } catch (Exception e) { e.printStackTrace(); } }

Разница между const LPSTR и const char*

Есть такой код:
const LPSTR str = "str"; const char* str2 = "str";
int main() { char* w = str; char* w2 = str2; //error: cannot convert from 'const char *' to 'char *' return 0; }
Почему появляется такая ошибка понятно. Но почему такой ошибки нет строчкой выше, когда используется LPSTR? Ведь это только typedef char* LPSTR;


Ответ

Потому что typedef - это не макрос, т.е. не текстовая подстановка. В
const LPSTR str = "str";
const уже относится к самому str, а не к указуемым данным. То есть это эквивалентно следующему объявлению
char *const str = "str";
Отличие от
const char* str2 = "str";
очевидно.
Поэтому и нет ошибки в char* w = str;

Формально в современном С++
const LPSTR str = "str";
является некорректным кодом. Указатель на некостантный char нельзя просто так поставить указывать на строковый литерал.

Сделать яйцо на Пасху на HTML

Задача – сделать пасхальное яйцо используя любые WEB технологии.
HTML, CSS, SVG, Canvas, JavaScript можно использовать любые техники и приёмы.


Ответ

Пасхальное яйцо с помощью Canvas и JavaScript:
var canvas = document.getElementById('canvas'), canvas2 = document.createElement('canvas'), ctx = canvas.getContext('2d'), ctx2 = canvas2.getContext('2d'); canvas2.width = canvas2.height = 50; ctx2.lineWidth = 5; ctx2.fillStyle = '#8f0'; ctx2.fillRect(0, 0, 50, 50); ctx2.strokeStyle = '#80f'; ctx2.fillStyle = '#0ae'; ctx2.beginPath(); ctx2.moveTo(0, 25); ctx2.lineTo(25, 0); ctx2.lineTo(50, 25); ctx2.lineTo(25, 50); ctx2.lineTo(0, 25); ctx2.stroke(); ctx2.fill(); ctx2.strokeStyle = '#8f0'; ctx2.fillStyle = '#00ae00'; ellipse(ctx2, 25, 25, 15, 15); ctx2.fill(); ctx2.fillStyle = '#80f'; ellipse(ctx2, 25, 25, 9, 9); ctx2.fill(); ctx2.stroke(); ctx.lineWidth = 2; //следующая строка будет работать не везде //ctx.ellipse(130, 195, 125, 170, 0, 0, 2 * Math.PI); ellipse(ctx, 130, 195, 125, 170); ctx.strokeStyle = '#80f'; ctx.fillStyle = ctx.createPattern(canvas2, 'repeat'); ctx.fill(); ctx.stroke(); ctx.font = 'bold 164px "Palatino Linotype",serif'; ctx.fillStyle = '#ddd'; ctx.fillText('ХВ', 20, 250); ctx.strokeText('ХВ', 20, 250); //stackoverflow.com/a/8372834/ function ellipse(ctx, cx, cy, rx, ry) { ctx.save(); ctx.beginPath(); ctx.translate(cx - rx, cy - ry); ctx.scale(rx, ry); ctx.arc(1, 1, 1, 0, 2 * Math.PI, false); ctx.restore(); }

Работает ли у вас Firebase?

Уже три дня как перестала работать база данных Firebase. То есть во всех приложениях тупо не выводится информация из базы, никаких ошибок не выдает. При входе в консоль показывает, что баз данных нет. При попытке создать новую выводит ошибку. Что такое и куда обращаться?


Ответ

РКН заблокировали IP-адрес, на котором находится сервер БД у Firebase. Во всех проектах теперь не видно БД. Авторизация через Firebase API не работает. При попытке создать новую БД выводится ошибка "Null". Я спрашивал у тех поддержки, и они подтвердили блокировку IP. Написал на горячую линию РКН, пока все глухо... Проверял на 4-ех интернет-провайдерах. Сами страдаем от этого. У пользователей не из России данной проблемы нет. Остается только ждать действий от Google или разблокировки...

Оптимизирует ли компилятор GCC данную запись?

Речь пойдёт об инициализации объектов. Большинство делают это следующим образом:
A a;
или же
A a(args);
в случае передачи аргументов в конструктор. Но что будет в случае записи, подобной используемой в C#? А именно:
A a = new A();
или же:
var a = new A();
в случае C++ это выглядит как
A a = A();
или же:
auto a = A();
Но будет ли компилятор оптимизировать данную запись до обычного A a();, где, в отличии от моего предложенного варианта, нет оператора =?


Ответ

Во-первых, во всех версиях спецификации С++ инициализация копированием при одинаковых типах левой и правой части сразу же рассматривается как прямая инициализация. То есть ваше
A a = A();
сразу же означает именно
A a(A()); // в условной записи, ведь на самом деле это объявление функции
К "оптимизациям" это пока не имеет никакого отношения.
Во-вторых, в С++11 будет ли этот вариант соптимизирован до
A a(); // в условной записи, ведь на самом деле это объявление функции
зависит от вашего компилятора. В любом случае, вы все равно обязаны предоставить доступный копирующий или перемещающий конструктор.
В-третьих, начиная с С++17 этот вопрос уже не имеет отношения к оптимизациям. В С++17 запись
A a = A();
сразу является просто альтернативной формой записи для
A a(); // в условной записи, ведь на самом деле это объявление функции

Как работает интернирование строк

коллеги!
хотела бы спросить вопросы, которые у меня возникли при более подробном изучении языка .NET и трудности касаются как минимум ссылочного типа string
1) Intern pool; (пулСтрок) Позволяет объединить строки с одинаковыми значениями в них в определенный пул памяти. В данном случае мы инициализировали две строки с одинаковыми значениями и они попали в один пул памяти. пример в моем понимании:
string a = "aaa"; string b = "aaa"; bool c = (object)a == (object) b; // И получаем true
ОДНАКО код:
string a = "aaa"; string b = "aa"; b+="a"; bool c = (object)a == (object) b; // И получаем false
Почему так? и как это работает? по сути мы получаем строку с одинаковыми значениями и все они должны ссылаться на один объект. почему мы по итогу получаем разные результаты? Я понимаю, что в данном случае мы сравниваем объекты, а не содержимое. Но почему они не объединились?


Ответ

В первом вашем примере строки интернируются на этапе компиляции. Если посмотреть в утилите ILDASM, то в окне MetaInfo в разделе User Strings будет представлен всего один экземпляр:
70000001 : ( 3) L"aaa"
Соответственно, обе переменные: и a, и b будут указывать на этот адрес.
Во втором примере в результате конкатенации тоже получается строка "aaa", но она не заносится по умолчанию в пул интернированных строк, потому что для этого нужны дополнительные проверки, то есть тратится время.
Во втором примере можно добавить строку в пул вручную:
string a = "aaa"; string b = "aa"; b += "a"; b = string.Intern(b); bool c = (object)a == (object)b; // True
Ответ на вопрос из комментария:
Я не уверен, но, думаю, выгода в том, что после интернирования переменная b станет указывать на тот же участок памяти, что и a. После чего сборщик мусора сможет убрать другой экземпляр строки "aaa". Это почти бессмысленно для коротких строк, но может оказаться выгодно для длинных долгоживущих строк.
Также нужно учитывать, что удалить строку из пула невозможно. Она так и будет висеть в памяти до конца работы приложения. Именно поэтому в рантайме строки не добавляются в пул по умолчанию.

Прерывистая рамка

Как сделать такую прерывистую рамку?

Без использования clip-path. Понимаю, что надо использовать псевдоэлементы с бордерами. Но их получится слишком много. Есть ли простой способ?


Ответ

Смотреть на весь экран
* { margin: 0; padding: 0; box-sizing: border-box; } html, body { height: 100%; } body { display: flex; justify-content: center; align-items: center; } .wrapper { width: 40rem; height: 20rem; background-image: url('https://images.unsplash.com/photo-1503264116251-35a269479413?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=281dd3518c2edb68c31b19bbcb624a0f&auto=format&fit=crop&w=1350&q=80'); padding: 1rem; } .wrapper .wrapper-img { width: 100%; height: 100%; background-image: linear-gradient(white, white), linear-gradient(90deg, white 150px, transparent 2vw), linear-gradient(transparent 15vw, white 15vw), linear-gradient(90deg, white 25vw, transparent 25vw, transparent 40vw, white 40vw); background-size: 4px 100%, 150px 4px, 4px 200px, 100% 4px; background-position: 0 0, 0 0, 100% 100%, 100% 100%; background-repeat: no-repeat, no-repeat, no-repeat, no-repeat; }

Таймер в Android-приложении

Как сделать таймер в android-приложении? Просто использовать java.util.Timer?


Ответ

Есть в ОС вот что — CountDownTimer А вообще вот Вам примерчик:
Timer timer = new Timer(); timer.schedule(new UpdateTimeTask(), 0, 1000); //тикаем каждую секунду без задержки //задача для таймера class UpdateTimeTask extends TimerTask { public void run() { ... } }
На самом деле, попробуйте сперва CountDownTimer. А, вспомнил. Вот вам еще дока
Только таймер работает один раз (тот что java.util.Timer), такая у него особенность, и нужно перехватывать IllegalStateException

Выгрузка данных в Excel в php

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


Ответ

Вот тут посмотри http://exls.ru Кратко: поддерживает шаблоны; выгружает в форматы .xls, .xls.gz, .zip; есть возможность расширять форматы; программировать на php не нужно; поддерживает входные параметры; поддерживает модули (например: выгрузка заголовков почты в excel); пойдет на любом хостинге. Я принимал участие в написании данной системы.

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

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


Ответ

Создаете элемент до которого нужно скролить и запоминаете его id:

content
Далее создаете ссылку или кнопку с указанием id элемента куда скролить: click me И собственно скрипт для скролинга: $(document).ready(function () { $("a").click(function () { var elementClick = $(this).attr("href"); var destination = $(elementClick).offset().top; if ($.browser.safari) { $('body').animate({ scrollTop: destination }, 1100); //1100 - скорость } else { $('html').animate({ scrollTop: destination }, 1100); } return false; }); }); В данном скрипте работает прокрутка, как вверх, так и вниз. UPD: добавлен полный пример страницы


scroll down
div

CONTENT
scroll up
div

Что происходит в оперативной памяти при прибавлении 1 к максимальному значению переменной?

Есть int с максимальным значением 2147483647. В оперативке выглядит так: 11111111111111111111111111111111 При прибавлении единицы число превращается в -2147483647 и 01111111111111111111111111111111 Из-за чего Происходит смена именно 1ой ячейки? Как выглядит этот процесс? p.s. буду благодарен тому, кто посоветует подходящую метку


Ответ

Никакой мистики, просто дополнительный код. У вас небольшая ошибка: число 2147483647 в дополнительном коде выглядит как 0111 1111 1111 1111 1111 1111 1111 1111 (31 единица), а -2147483648 - 1000 0000 0000 0000 0000 0000 0000 0000 (единица и 31 ноль).

C++: изменение символа строкового литерала

#include
int main() { char* str = "qwerty"; str[0] = '1'; std::cout << str << std::endl; return 0; }
Этот код выдает ошибку access violation. В чем дело? Почему нельзя изменить символ простой не-const строки?
UPD: код сработал при такой инициализации строки: char str[]. Но в чем разница?


Ответ

Строковые константы в коде могут размещаться где-то в отдельном блоке памяти (в дата-секции исполняемого файла, например), который может быть отмечен как "только для чтения". Модифицировать их нельзя, это undefined behavior. Хотя на некоторых компиляторах в некоторых осях при определённых условиях это и может работать, но полагаться на это нельзя.
Если хотите иметь модифицируемую строку, то скопируйте её или объявите как массив (не как указатель).
См. Why is this string reversal C code causing a segmentation fault?

Как получить полное имя файла в одну команду?

Как получить полное (с путём относительно /) имя файла в одну команду?
Бывает, работаешь в консоли, и нужно скопировать /полный/путь/к/файлу, например, чтобы в соседней консоли использовать его как аргумент для scp. Приходится вызывать pwd, чтобы скопировать путь к текущей папке, и ls, чтобы скопировать имя файла. Можно ли это сделать в одну команду?


Ответ

readlink -f покажет /полный/путь/к/файлу.ext, дополнительно "раскрыв" все символические ссылки и заменив их на "канонические" пути. Пример показателен:
$ cd /tmp $ mkdir foo $ touch foo/bar.ext $ ln -s foo/bar.ext baz.ext $ readlink -f foo/bar.ext /tmp/foo/bar.ext $ readlink -f baz.ext /tmp/foo/bar.ext
Здесь /tmp/baz.ext является симлинком на /tmp/foo/bar.ext
Предложенное решение работает в Linux и FreeBSD, но не работает в Mac OS - у них там своя атмосфера

Создание makefile

Пытаюсь разобраться в написании грамотного make файла, это ад.
Есть такие файлы: SubClass.h/.cpp, SuperClass.h/.cpp, Main.cpp.
Сконструировал такой makefile:
Programm: Main.o SuperClass.o SubClass.o g++ -o Programm Main.o SuperClass.o SubClass.o Main.o: Main.cpp SuperClass.o SubClass.o g++ -c -o Main.o Main.cpp SuperClass.o: SuperClass.h SuperClass.cpp g++ -c -o SuperClass.o SuperClass.cpp SubClass.o: SubClass.cpp SubClass.h SuperClass.o g++ -c -o SubClass.o SubClass.cpp
Классно бы это автоматизировать и разделить по директориям /h /cpp /o файлы.
Нашел хороший способ получать зависимости (через include bash добавил в makefile)
g++ -MM SubClass.cpp SubClass.o: SubClass.cpp SubClass.h SuperClass.h
А нужно что бы выхлоп был SubClass.o: SubClass.cpp SubClass.h SuperClass.o, не понимаю, как мне этого добиться с помощью make? Я явно делаю что то не так.
Через wildecard научился получать список файлов в папке, а вот в подпапках как (нахождение самих подпапок и тд)?
Это ведь такая простая и популярная модель организации проекта, неужели нет ничего готового? Возможно я пишу велосипед? :D
PS: Я не прошу что то писать за меня, просто наведите в нужное направление.


Ответ

мне кажется, ваш файл несколько многословен. для всех описанных действий, кажется, достаточно таких строк:
Programm: Main.o SuperClass.o SubClass.o g++ -o $@ $^
запуск make с параметром -n (dry-run) показывает такую последовательность команд (при наличии в текущем каталоге только cpp- и h-файлов):
g++ -c -o Main.o Main.cpp g++ -c -o SuperClass.o SuperClass.cpp g++ -c -o SubClass.o SubClass.cpp g++ -o Programm Main.o SuperClass.o SubClass.o

немного объяснений по поводу «применённой магии»
«магия» называется implicit rules
все актуальные implicit rules (и ещё многое другое) можно посмотреть командой make -p | less
к примеру, о том, что из file.cpp можно собарть file.o (и, главное, как это сделать), make «знает» благодаря вот такому правилу:
%.o: %.cpp # recipe to execute (built-in): $(COMPILE.cpp) $(OUTPUT_OPTION) $<

Что выбрать ASP.NET MVC или SharePoint для Enterprise? [закрыт]

На работе необходимо будет реализовать систему аналитической отчетности. Содержащую различные отчеты с множеством данных, полей колонок и фильтром, детальных отчетов и т.д. Сейчас она реализована в собственной системе отчетности, но руководители хотят видеть более современный дизайн и поддержку в браузерах. Так же в данный момент система работает в локальной сети организации, но будет необходимо реализовать доступ к отчетам через сеть Интернет.
Изначально в планах было реализовать систему на ASP.NET MVC 5. Но руководство вспомнило что в предприятии куплен SharePoint (2010 или 2013). Он интегрирован с Lync и Outlook, что удобно. Встал вопрос что использовать.
Разрабатывать систему придется начинать мне. Дали время решить что лучше использовать. Но опыт есть только в ASP.NET MVC. После прочтения некоторых статей, стал сомневаться в своем изначальном выборе MVC. SharePoint так же показался привлекательным со своими плюсами.
Систему что на ASP.NET MVC, что на SharePoint придется реализовывать с нуля. Выбор технологии для разработки системы предстоит сделать из стека Microsoft.
Очень важно услышать мнение более опытных и авторитетных людей на счет.
Если можно, то выскажитесь в соответствии с вашим опытом или знаниями, как ASP.NET MVC и SharePoint подходят под эти критерии:
Создание удобного пользовательского интерфейса (скорее простота создания, т.к. скорее всего будет использован Bootstrap; Простота и скорость разработки (если учесть что разработка будет с нуля и мои познания ограничиваются ASP.NET MVC); Возможность простого развертывания и настройки сервера для доступа из сети Интернет; Настройка безопасности: авторизации, роли, шифрование и т.п.; На что еще нужно обратить внимание?


Ответ

Если есть возможность - не используйте sharepoint! Мы сейчас делаем на нем сложный проект - и стабильно каждую неделю случается, что что-то в шарике просто не работает из-за неучтенных изменений, накопившихся в нем ранее. (Пример - сейчас не могу создать lookup field ни в одном списке через веб-интерфейс из-за того, что не загружается список списков - а не загружается он потому что какой-то из списков где-то на сайте "битый").
Если делать для шарика решение - это тихий ужас. Вместо современного ASP.NET MVC - устаревший ASP.NET WebForms. Шарик должен стоять на каждом компе разработчика - иначе студия не сможет даже открыть проект. Шарик должен стоять даже на билд-агенте! Иногда общую для нескольких проектов сборку приходится деплоить в GAC. После этого эту сборку надо обновлять в GACе каждый раз перед использованием - то есть нельзя даже консольную утилиту отладить или тесты прогнать без деплоя решения на сервер.
С автоматическим деплоем - тоже веселье. После установки решения на ферму надо отдельно активировать его возможности (они же фичи). Причем активировать их нельзя пока решение не установится полностью - а команды дождаться нету. Более того, нет простого и очевидного способа определить, устанавливается сейчас решение или не смогло установиться - в обоих случаях будет статус NotDeployed. Кстати, можно запросто удалить решение без деактивации его фич. После этого фичи уже невозможно деактивировать (да, вот так у меня на рабочем компе и появился битый список из первого абзаца).
Если же делать для шарика не решение, а приложение - то всей этой радости, разумеется, не возникает. Но и возможностей тут куда меньше. И тут возникает другой вопрос... Каждое приложение - отдельный сайт. Зачем приложению вообще нужен шарик, что от него можно получить?
Авторизация пользователей? Но шарик использует внешнюю STS для этих целей, без нее просто не будет работать связь с приложениями. Но тогда и текущего пользователя можно узнавать не у шарика, а у STS.
Хранилище данных? Но у шарика очень тормозные списки. Что неудивительно, если покопаться в их внутреннем устройстве.
Управление конфигурацией? Но если делать автоматическое развертывание - то шарик не упрощает процесс, а лишь ставит палки в колеса.
В итоге получается, что шарик как платформа не может предоставить ничего интересного, что можно было бы использовать.

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

UPD. По пунктам из вопроса.
Пользовательский интерфейс на WebPages делать удобнее нежели на WebForms. А решения шарика используют WebForms. Разрабатывать решения под шарик очень сложно. В документации на msdn нет даже такой важной информации, какие объекты надо закрывать, а какие не надо. Точнее, информация есть - но в отдельной статье, а не в доках по классам. И все такие статьи придется найти и выучить. Установка решения на шарик вручную, через веб-интерфейс - довольно простая. Но ее автоматизация - это ад. Кроме того, само по себе развертывание шарика - тоже тот еще ад. У шарика есть красивый веб-интерфейс для редактирования прав. Но только для встроенных в шарик же объектов.
У ASP.NET MVC куда больше возможностей по управлению безопасностью именно с точки зрения программиста.
Разумеется, все вышеперечисленное относится к решениям шарика, а не приложениям. Приложение пишется на том же ASP.NET MVC и лишено подобных недостатков. Но тут мы возвращаемся к проблеме "зачем вообще приложению шарик".

Внутренние и вложенные классы

Внутренние и вложенные классы — это не одно и тоже.
В чем разница, и когда принципиально нужно использовать один, а когда другой?


Ответ

Статические вложенные классы, не имеют доступа к нестатическим полям и методам обрамляющего класса. Поведение точно такое же, как у статических методов класса. Доступ к нестатическим полям и методам может осуществляться только через ссылку на экземпляр обрамляющего класса.
Но static nested классы имеют доступ к любым статическим методам внешнего класса, в том числе и к приватным.
public class Mememe{ private static int m_AccessableInt; // доступно в StaticNestedMememe private int m_NotAccessableInt; // не доступно в StaticNestedMememe [...]
public static class StaticNestedMememe{ [...] } }
Применение? Например, если вложенный класс имеет смысл только в контексте обрамляющего класса.
Так же многие используют такие классы для реализации паттерна Builder
Экземпляр такого класса нужно создавать, используя имя обрамляющего класса:
Mememe.StaticNestedMememe nestedObject = new Mememe.StaticNestedMememe();
Внутренние классы бывают трёх типов:
локальные классы (local classes); анонимные классы (anonymous classes); внутренние классы-члены (member inner classes).
Локальные классы определяются внутри блока кода.
public class Mememe{ public void calc(String requestPath) { class Сalculator{ int calc() { return 0; } } } }
Локальные классы имеют доступ к полям и методам обрамляющего класса. Локальные классы:
видны только в пределах блока, в котором объявлены; не могут быть объявлены как private, public, protected или static не могут иметь внутри себя статических объявлений; исключением являются константы (static final);
Анонимный класс (anonymous class) - это локальный класс без имени.
Типичный пример - реализация Runnable
new Thread(new Runnable() { public void run() { ... } }).start();
Основное ограничение при использовании анонимных классов - это невозможность описания конструктора, так как класс не имеет имени.
Внутренние классы-члены ассоциируются не с самим внешним классом, а с его экземпляром. При этом они имеют доступ ко всем его полям и методам. Например:
public class OuterClass { public void method() { ... }
public class InnerClass { public void method() { ... }
public void anotherMethod() { method(); } } }
InnerClass имеет доступ в членам класса OuterClass, как видно на примере метода anotherMethod, который вызывает метод method
Создать такой класс можно так:
OuterClass outer = new OuterClass(); OuterClass.InnerClass innerClass = OuterClass.new InnerClass ();

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

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


Ответ

Делается так:
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); ClipData clip = ClipData.newPlainText("", editText.getText().toString()); clipboard.setPrimaryClip(clip); } });

Регулярное выражение для получения id пользователя

В общем, нужно вывести из строки id пользователя до запятой. В данном коде выводит "id50,", надо только "50". Как?)
text = 'id50, 4124fdgfgdfg'; if(text.match('id[0-9].*,')){ komy = text.match('id[0-9].*,'); alert(komy); }


Ответ

С помощью регулярного выражения ^id(\d+),.*$ (захватывается число в скобках после id, и до запятой). Можно сразу захватить и вторую часть (4124fdgfgdfg), таким выражением: /^id(\d+), (.*)$/
Рабочий пример:
str = 'id42, 4124fdgfgdfg'; if (m = str.match(/^id(\d+), (.*)$/)) { console.log(m[1], m[2]) }
Дает в консоль (можете нажать кнопку "Выполнить код" для проверки):
42 4124fdgfgdfg
Здесь хорошее описание match на русском: https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/String/match
Здесь https://regex101.com/ вы можете онлайн поиграть с регулярными выражениями и сразу видеть результат. Вот ваш пример с тестами и комментариями: https://regex101.com/r/nX1rF5/2

css: background в разных браузерах

Есть вот такой фон на css:
background-image: linear-gradient(45deg, transparent,transparent 48%, rgba(255,255,255,.4) 48%, rgba(255,255,255,.4) 52%, transparent 52%);
Подскажите, пожалуйста, как правильно в стиле прописать этот фон для браузеров -webkit-, -moz-, -ms-, -o-? Спрашиваю, потому как не совсем понимаю, как это правильно сделать, т.к. в этом случае добавление к селектору одной приставки мало, и в блоке объявления стилей это прописывается для каждого браузера по-разному.


Ответ

Нужно добавить соответствующие префиксы к linear-gradient
При этом, если некий браузер поддерживает несколько реализаций, то более новые должны идти позже более старых (поскольку с ними меньше проблем). По той же причине вариант без префиксов должен идти последним.
Замечу, что у браузеров появилась тенденция поддерживать префикс -webkit, поэтому его стоит написать первым. Да и вообще, довольно распространённая практика - писать префиксы в порядке убывания длины:
-webkit-smth -khtml-smth -moz-smth -ms-smth -o-smth smth
Возвращаясь к linear-gradient и вспоминая, что у webkitа есть более старая форма, получим такой порядок:
background-image: -webkit-gradient(45deg, transparent, transparent 48%, rgba(255,255,255,.4) 48%, rgba(255,255,255,.4) 52%, transparent 52%); background-image: -webkit-linear-gradient(45deg, transparent, transparent 48%, rgba(255,255,255,.4) 48%, rgba(255,255,255,.4) 52%, transparent 52%); background-image: -moz-linear-gradient(45deg, transparent, transparent 48%, rgba(255,255,255,.4) 48%, rgba(255,255,255,.4) 52%, transparent 52%); background-image: -ms-linear-gradient(45deg, transparent, transparent 48%, rgba(255,255,255,.4) 48%, rgba(255,255,255,.4) 52%, transparent 52%); background-image: -o-linear-gradient(45deg, transparent, transparent 48%, rgba(255,255,255,.4) 48%, rgba(255,255,255,.4) 52%, transparent 52%); background-image: linear-gradient(45deg, transparent, transparent 48%, rgba(255,255,255,.4) 48%, rgba(255,255,255,.4) 52%, transparent 52%);
Ещё про градиенты стоит отметить, что префиксные варианты используют from-синтаксис, а принят в итоге был to
background: -webkit-linear-gradient(top, white 0%, black 100%); background: linear-gradient(to bottom, white 0%, black 100%);
PS: А вообще, стоило бы воспользоваться автопрефиксером или генератором градиентов.

Как начать делать текстовый квест?

Нужно реализовать класс Quest в котором будут хранятся шаги.
Шаги представляют собой класс с каким-то текстом и вариантами выбора. Пользователь сам добавляет шаги и варианты выбора, которые в свою очереди ведут к следующим шагам (сценам) в зависимости от выбора игрока. Как я понимаю каждый выбор должен иметь ссылку на следующий шаг (сцену). Но как это реализовать в коде не понимаю.


Ответ

В общем, @VladD абсолютно прав, вам нужен конечный автомат (в английской терминологии state machine), и желательно разобраться что это такое подробнее, но я попробую показать простой для понимания пример не используя пока специфическую терминологию.
Вам попадались книги-игры Дмитрия Браславского? В прочем если бы попадались, вопрос бы не возник.
И так, что такое текстовый квест? Это набор параграфов, описывающих некоторые игровые сцены в которых игроку требуется принять некоторое решение, чтобы перейти к другой сцене. Ок, от этого и пойдем.
Пронумеруем все параграфы в произвольном порядке. Для книги нумерация имеет значение, для компьютерного варианта - нет. Размещаем параграфы в массив согласно сделанной нумерации. Каждый выбор игрока, фактически, означает выбор следующего параграфа, но выбор в слепую, т.к. игрок не знает содержимое параграфа (во всяком случае в первой игре). Таким образом, необходимо сопоставить предлагаемые игроку действия на текущей сцене с номерами параграфов на который они ведут. Когда игрок сделал свой выбор, мы просто показываем ему текст следующего параграфа с соответствующим индексом в массиве и ожидаем следующего выбора игрока, разумеется если это выбор у него есть в данной сцене.
Естественно возможен вариант, когда игрок может попасть на одну и туже сцену (параграф) разными путями.
Таким образом, вам достаточно одного единственного класса для описания модели вашего квеста, при этом ни чего мудреного не требуется. Для консольного варианта достаточно базовых знаний C#: синтаксис, условия, массивы, циклы. ну и немного стандартных классов для организации ввода/вывода.
В эту модель прекрасно вписывается и "боевка" с бросанием кубиков, и применение ранее приобретенных вещей, если сцена предполагает возможность их применения.
Какую к данной модели приделать "шкурку": консоль, или развесистый графический интерфейс с иллюстрациями и музыкой, не имеет значения, т.к. самое сложное в данном типе игр - создать сюжет и написать тексты игровых сцен, чтобы они не были все на одно лицо.
Единственное что я бы посоветовал лично от себя - не показывайте игроку настоящие номера параграфов, спрячьте их за кнопками с текстом, локальными номерами (1,2,3 и т.д. по количеству вариантов выбора в сцене) для консоли, ссылками для Web-версии. Так интереснее, и больше вероятность, что игрок хотя бы прочитает (а может и запомнит) текст над которым вы или ваш сценарист трудились, создавая квест.

Ну и немного кода для иллюстрации возможной (но не единственной) реализации такой модели:
Простейший вариант для консоли с одним классом:
class Quest { public string[] Paragraphs {get; set;} public int[][] Choises {get; set;} //Для консольного варианта вы просто отображаете номера для выбора прямо в тексте //параграфа, рядом с описанием выбора, как в книжном варианте. }
Более сложный пример:
class Paragraph //параграф (игровая сцена) { public int Num {get; set;}//не особо нужен, но для полной картины пусть будет public string Text {get; set;} //доступные варианты, список может быть нулевой длины, но не null. public List Choises {get;} = new List(); }
class Choise { public int NextParagraph {get; set;} public string Text {get; set;} //текст варианта выбора для игрока }
class Quest { Paragraph Current {get; set;} //Если номера параграфов соответствуют индексам можно так List {get;} = new List(); //Если лень следить за соответствием - так Dictionary {get;} = new Dictionary(); }
Если знаете что такое направленный граф, то можно еще проще
class Paragraph //параграф (игровая сцена) { public string Text {get; set;} //текст параграфа //доступные варианты, список может быть нулевой длины, но не null. public List Choises {get;} = new List(); }
class Choise { public Paragraph Next {get; set;} public string Text {get; set;} //текст варианта выбора для игрока }
class Quest { Paragraph Current {get; set;} Paragraph StartPoint {get; set;}; }
С кодом ввода выбора игрока и вывода текста на экран, думаю сами справитесь.

Может ли NULL давать не нулевое значение?

При программировании часто использую подобное выражение:
if (pointer) { .... }
что эквивалентно (по крайней мере для моей системы):
if (pointer != NULL)
где pointer указатель. Хочу удостовериться, что этот код не несет в себе опасности на других системах и т.д. В учебнике нашел только, что NULL возвращает значение не указывающее ни на какой объект. Но равно ли это значение 0 априори?


Ответ

Также внесу некоторые дополнения к ответам, которые дали @alexolut и @VladD.
Как вообще C решает истинно выражение expression в операторе if или нет:
if ( expression ) statement if ( expression ) statement else statement
?
Пункт 6.8.4.1 / 2 говорит следующее:
In both forms, the first substatement is executed if the expression compares unequal to 0. In the else form, the second substatement is executed if the expression compares equal to 0. [...]
То есть, выражение expression сравнивается с нулём. Если оно не равно нулю, то выражение expression считается истинным, если оно равно нулю, то expression считается ложным.
Таким образом, примеры в вашем вопросе интерпретируются так:
if ( pointer != 0 ) if ( (pointer != NULL) != 0 )
В стандарте языка явно оговорено (6.3.2.3 / 3), что и 0, и (void *)0, и NULL — нулевые указательные константы (null pointer constant). Для целей сравнения указателя и нулевой указательной константы, нулевая указательная константа преобразуется к типу указателя (6.5.9 / 5):
[...] If one operand is a pointer and the other is a null pointer constant, the null pointer constant is converted to the type of the pointer. [...]
Результат такого преобразования — нулевой указатель (null pointer). Если pointer не является нулевым указателем, то согласно пункту 6.5.9 / 6, оба выражения: pointer != 0 и pointer != NULL — истинны.
Некоторого пояснения заслуживает выражение (pointer != NULL) != 0. Относительно операторов != и == стандарт языка говорит следующее (6.5.9 / 3):
[...] Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int. [...]
Таким образом, если pointer — не является нулевым указателем, то выражение (pointer != NULL) — равно 1, а значит выражение (pointer != NULL) != 0 истинно.

непонятное поведение аргумента функции

когда вызываю функцию прямо в ostream, не получаю нужный результат, а когда вызываю до cout, то все нормально...
#include #include using std::string;
string pop_word(const char*& p) { const char* q = p; size_t count = strlen(q); string s = p; while (!isdigit(*q) && --count > 0) ++q; string str = s.substr(0, q - p); while (*q == ' ' && --count > 0) ++q; if (*q) p = q; return str; }
int main() { const char* p = "unsigned 45678"; const char* q = p;
string s = pop_word(p); std::cout << s << '
' << p << '
'; // p указывает на "45678" (все нормально)
std::cout <' << q; //почему q указывает на "unsigned 45678"? return 0; }
Заранее извените за плохо изложенный вопрос, и спасибо за внимание и ответ


Ответ

Наблюдаемое вами поведение вызвано тем, что ваш компилятор не удовлетворяет требованиям С++17 или работает в до-C++17 режиме.
До С++17 порядок вычисления аргументов в выражении
std::cout << pop_word(q) << '
' << q;
был не специфицирован. Компилятор имел право сначала вычислить (подготовить, передать) аргумент q, а затем вычислить аргумент pop_word(q). А мог поступить и наоборот. Так как pop_word(q) изменяет значение q, результат отличался бы в этих случаях.
Но начиная с С++17 левый операнд <<, как для встроенного, так и для перегруженного оператора, должен вычисляться до того, как вычисляется правый (спасибо @wololo за подсказку). Это означает, что в данном выражении вывод однозначен
unsigned 45678
P.S. Что интересно, GCC в режиме -std=c++17 -Wsequence-point все равно продолжает предупреждать о неопределенном поведении в
int i = 0; std::cout << ++i << ++i << ++i << std::endl;
хотя в С++17 никакого неопределенного поведения тут не должно быть.

Столкнулся с проблемой, когда модель содержит много свойств. Как писать эффективнее?

Дело в том, что впервые столкнулся с моделью, где более 40 свойств, которые нужно отобразить.
[Display(Name = "Название 1")] public string Name1 { get; set; } [Display(Name = "Название 2")] public int Name2 { get; set; } [Display(Name = "Название 3")] public int Name3 { get; set; } [Display(Name = "Название 4")] public int Name4 { get; set; }
В представлении мне нужно отобразить данные в виде таблицы

@Html.LabelFor(c => common.Name1) @Html.LabelFor(c => common.Name2) @Html.LabelFor(c => common.Name3)

Мне кажется нелогичным такой способ вывода информации и подозреваю, что можно сделать это более легким способом, который пока не смог найти... Подскажите, пожалуйста.
Есть ли что-либо похожее на это
@{ foreach(var DisplayName in Model.ObjectPropertyAttributies) }
DisplayName


Ответ

Если по работе нужно создавать много однотипных файлов то можно в сторону кодогенерации посмотреть: https://msdn.microsoft.com/en-us/library/bb126445.aspx
Я это использую, чтобы делать заготовки под view model:
<#@ template debug="true" hostSpecific="false" #> <#@ output extension=".cs" #>
<#@ Assembly Name="System.Core" #> <#@ Assembly Name="$(SolutionDir)packages\Prism.Core.6.2.0\lib
et45\Prism.dll" #>
<#@ import namespace="System" #> <#@ import namespace="Prism.Mvvm" #> <# // This template generates the code for a ViewModel which is based on some model. // Also supposed that used MVVM pattern and Prism Library
// Full name of type for which will be generated ViewModel Type modelType = typeof(someType); PopulateTypeNameProperties(modelType);
// Namecpase inside which the code of ViemModel will be put string space = "Solution.ViewModel";
// Begining template's code #>namespace <#= space#> { // usings using <#= modelType.Namespace#>;
public class <#= modelType.Name #>ViewModel : BindableBase { #region Fields
<# foreach(var tuple in this.typeNameProperties) { #> private <#= tuple.Item1 #> <#= tuple.Item3 #>; <#}#>
#endregion
#region Property for binding
<# foreach(var tuple in this.typeNameProperties) { #> public <#= tuple.Item1 #> <#= tuple.Item2 #> { get { return this.<#= tuple.Item3 #>; }
set { this.SetProperty(ref this.<#= tuple.Item3 #>, value); } }
<#}#>
#endregion
public <#= modelType.Name #>ViewModel() {}
public <#= modelType.Name #>ViewModel(<#= modelType.Name #> model) { <# foreach(var tuple in this.typeNameProperties) { #> this.<#= tuple.Item3 #> = model.<#= tuple.Item2 #>; <#}#>}
public void UpdateViewModel(<#= modelType.Name #> model) { <# foreach(var tuple in this.typeNameProperties) { #> this.<#= tuple.Item2 #> = model.<#= tuple.Item2 #>; <#}#>}
public static explicit operator <#= modelType.Name #> (<#= modelType.Name #>ViewModel viewModel) { <# int beforeLast = typeNameProperties.Count - 1; #> return new <#= modelType.Name #> { <# for (int i = 0; i < beforeLast; ++i) { #> <#= typeNameProperties[i].Item2 #> = viewModel.<#= typeNameProperties[i].Item3 #>, <#}#><# if (typeNameProperties.Count > 1) { this.Write(string.Format("\t\t{0} = viewModel.{1}", typeNameProperties[beforeLast].Item2, typeNameProperties[beforeLast].Item3)); } this.Write("
"); #> }; } } } <# // Ending template's code #> <#+ // The storage for couple type - name of Properties private List> typeNameProperties = new List>();
private void PopulateTypeNameProperties(Type modelType) { foreach (var p in modelType.GetProperties()) { if (string.CompareOrdinal(p.Name, "ErrorMessage") == 0) { continue; }
string type = GetShortTypeName(p.PropertyType.Name);
var name = p.Name; char firstLetter = name[0]; var property = char.ToUpperInvariant(firstLetter).ToString() + name.Substring(1); var field = char.ToLowerInvariant(firstLetter).ToString() + name.Substring(1);
typeNameProperties.Add(new Tuple(type, property, field)); } } #>
<#+ private string GetShortTypeName(string typeName) { switch(typeName) { case "Int32": return "int";
/ .......
case "Object": return "object";
default: return typeName; } }
#>
Правда есть немного заморочек с отступами, и выглядит не очень читабельно. Но не нужно тратить время на медитативный набор свойств view model. Результат вот такой:
namespace Solution.ViewModel { // usings
public class CurrencyInfoViewModel : BindableBase { #region Fields
private string name; private string shortName; private DateTime modifyTime; private int id;
#endregion
#region Property for binding
public string Name { get { return this.name; }
set { this.SetProperty(ref this.name, value); } }
public string ShortName { get { return this.shortName; }
set { this.SetProperty(ref this.shortName, value); } }
public DateTime ModifyTime { get { return this.modifyTime; }
set { this.SetProperty(ref this.modifyTime, value); } }
public int Id { get { return this.id; }
set { this.SetProperty(ref this.id, value); } }
#endregion
public CurrencyInfoViewModel() {}
public CurrencyInfoViewModel(CurrencyInfo model) { this.name = model.Name; this.shortName = model.ShortName; this.modifyTime = model.ModifyTime; this.id = model.Id; }
public void UpdateViewModel(CurrencyInfo model) { this.Name = model.Name; this.ShortName = model.ShortName; this.ModifyTime = model.ModifyTime; this.Id = model.Id; }
public static explicit operator CurrencyInfo (CurrencyInfoViewModel viewModel) { return new CurrencyInfo { Name = viewModel.name, ShortName = viewModel.shortName, ModifyTime = viewModel.modifyTime, Id = viewModel.id }; } } }

Что означает запись вида 192.168.0.0/16 ?

Помогите осознать значение /16. Или вот пример из книги: fe80::f00 = fe80:0000:0000:0000:0000:0000:0000:0f00 fe80::f00/64 = fe80:0000:0000:0000:****:****:****:**** = fe80::/64


Ответ

Это записи так называемых бесклассовых сетей. 192.168.0.0 - это понятная для людей запись четырехбайтовых адресов протокола Internet версии 4. /16 - означает первые 16 бит = 2 байта в этой записи - маска подсети. Другие два байта описывают адрес конкретного узла в этой подсети (от 0.1 до 254.254). 192.168.0.0/24 уже значило бы подсеть 192.168.0 с адресами внутри нее от единицы до 254. fe80::f00 = fe80:0000:0000:0000:0000:0000:0000:0f00 fe80::f00/64 = fe80:0000:0000:0000:****:****:****:**** = fe80::/64 Приведенный выше пример показывает краткую нотацию адресов протокола Internet версии 6. Как видно их принято записывать в виде шестнадцатеричных октетов разделенных двоеточиями. Два идущих подряд двоеточия означают большую последовательность нулевых октетов (байтов). /64 означает то же самое что и в версии 4 - маску подсети.

Для чего нужны файлы *.h?

Начинаю изучать Visual С++ (2010), раньше пользовался паскалем, поэтому: не совсем понимаю, для чего нужны заголовочные файлы; что конкретно в них прописывается (должно прописываться).


Ответ

Если говорить применительно паскаля/делфи, то хедер - это фактически iterface секция, тогда *.с, *.cpp - это implementation часть. Грубо, конечно, но на первое время достаточно.

Что такое юнит-тесты? [закрыт]

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


Ответ

Я бы предложил вам выбрать стратегию тестирования, например, начать с простейших: черного и белого ящиков. При использования метода черного ящика вы знаете то, что вам необходимо подать на вход, и соответственно, что вы получите на выходе для данного входа. А значит вы можете составлять тесты исходя из этих знаний. Например для сложения чисел, у вас таблица из трех столбцов, первые два - входные значения, третий - результат. Проверяя по таблице работу вашей программы вы получите (в зависимости от количества проведенных тестов) % верных решений. Обычно такие тесты называют системными (Sytem tests). Они более общие. Например, если у вас система из 5ти модулей, вы будете тестировать всю систему сразу, так как вы не знаете, что должно быть на входе и выходе любого из модулей, а знаете только общий результат. При использовании метода белого ящика - вы знаете всю логику программы, так вы можете проверить каждую часть своей программы: операторы, условия, вводимые значения и т.п. Обычно данный тип тестов называется юнит-тестом. Это тест, в котором вы проверяете работу не всей программы, а ее отдельных (атомарных в какой-то степени) частей. Рассматривая предыдущий пример с 5ю модулями, вам известен вход и выход всех, вы можете тестировать каждый в отдельности или комбинировать их последовательность (заданную логикой программы, естественно).

Json как парсить на Java?

Здравствуйте! Есть вот такой ответ от сервера:
{ "p_result": "ok", "p_item": [ { "p_id": 132, "p_name": "Николай" }, { "p_id": 133, "p_name": "Светлана" } ] }
Если правильно понимаю, то это массив. Нужно написать метод который будет по параметру находить нужный элемент что то наподобие :
_http.getArrayParamValue("p_name");
Никак не могу сообразить.
p.s. думаю для меня было бы полезнее некое указание, нежели ссылка на очерендую библиотеку. Спасибо!
Решение. Ошибку тоже понял. @Josfey Спасибо огромное. Вы очень мне помогли!
String str = null; String input = "данные полученные от сервера";
JsonParser parser = new JsonParser(); JsonObject mainObject = parser.parse(input).getAsJsonObject(); JsonArray pItem = mainObject.getAsJsonArray("p_item");
for (JsonElement user : pItem) {
JsonObject userObject = user.getAsJsonObject(); userObject.get("p_id"); str = userObject.get("p_id").toString(); }


Ответ

Не совсем понял, что именно вы хотите извлечь из приведённой json-структуры, но вот, например, как извлечь из неё имя пользователя c id = 132 с помощью GSON
String input = "тут ваша json-структура"; JsonParser parser = new JsonParser(); JsonObject mainObject = parser.parse().getAsJsonObject(); JsonArray pItem = mainObject.getAsJsonArray("p_item"); for (JsonElement user : pItem) { JsonObject userObject = user.getAsJsonObject(); if (userObject.get("p_id").getAsInt() == 132) { System.out.println(userObject.get("p_name")); return; } }