Страницы

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

среда, 21 ноября 2018 г.

Laravel + Angular JS

Доброго времени суток, всех с наступающим. Возможно ли заставить работать вместе Angular JS и Laravel? Laravel использует шаблонизатор Smarty, и есть подозрение, что синтаксис Angular JS и Smarty будут конфликтовать. Посоветуйте, пожалуйста, как сделать так, чтобы они мирно существовали, и можно было использовать и то, и то. Всех с наступающим, всех благ вам в наступающем 2015.


Ответ

Есть 2 решения конфликта фигурных скобок. 1) Универсальное (подходит не только для smarty, но и для twig в Symfony2), с помощью изменения $interpolateProvider angular.module('myApp', []).config(function($interpolateProvider){ $interpolateProvider.startSymbol('[[').endSymbol(']]'); }); С этим кодом нужно будет оборачивать ангуляровские переменные в двойные квадратные скобки, например: [[ $item.name ]] 2) Решение от smarty, тэг {literal}, внутри этого тэга шаблонизатор не интерпретирует код: {literal}{{ $item.name }}{/literal}

Как узнать свой логин

Подскажите, пожалуйста, как узнать имя пользователя, который сейчас залогинен в linux? Т.е. свой логин. Нужен аналог whoami, для использования в коде программы.


Ответ

#include
int getlogin_r(char *buf, size_t bufsize);
или классический способ:
/* whoami.c */ #define _PROGRAM_NAME "whoami" #include #include #include
int main(int argc, char *argv[]) { register struct passwd *pw; register uid_t uid; int c;
uid = geteuid (); pw = getpwuid (uid); if (pw) { puts (pw->pw_name); exit (EXIT_SUCCESS); } fprintf (stderr,"%s: cannot find username for UID %u
", _PROGRAM_NAME, (unsigned) uid); exit (EXIT_FAILURE);
}
enSO - How to get the username in C/C++ in Linux?

Не работает валидация форм с помощью Bootstrap

Доброго времени суток, форумчане!
Подскажите пожалуйста, почему не работает валидация формы. Делаю всё, как тут: jQuery Validate Demo и тут Validate a Form using jQuery and Bootstrap Validator
Может что-то не так с файлом скрипта? Или подключаю его как-то не так? Код скрипта, взятый из примера и переделанный под мои нужды:
$(document).ready(function () { $('#timeValidationForm').bootstrapValidator({ container: '#messages', feedbackIcons: { valid: 'glyphicon glyphicon-ok', invalid: 'glyphicon glyphicon-remove', validating: 'glyphicon glyphicon-refresh' }, fields: { time: { validators: { notEmpty: { message: 'The full name is required and cannot be empty' } }, stringLength: { min: 1, max: 5, message: 'Input must be larger than 1 and less than 5' } } } }); });
Код html. Нужно заметить, что валидация поля происходит в модальном окне и должна работать без нажатия кнопки "submit":
@using( Html.BeginForm("ClockChanger", "Clocks", FormMethod.Post, new{@id="timeValidationForm", @class="form-horizontal"} ) ) {

}
Скрипт подключаю в теге с помощью


Ответ

В коде инициализации валидатора ошибка - скобка поставлена неверно и поле stringLength не входит в объект validators
$(document).ready(function () { $('#timeValidationForm').bootstrapValidator({ container: '#messages', feedbackIcons: { valid: 'glyphicon glyphicon-ok', invalid: 'glyphicon glyphicon-remove', validating: 'glyphicon glyphicon-refresh' }, fields: { time: { validators: { notEmpty: { message: 'The full name is required and cannot be empty' }, stringLength: { min: 1, max: 5, message: 'Input must be larger than 1 and less than 5' } }, } } }); });
Исправленный вариант в fiddle

Поиск ближайшего делителя

Задача. Даны два числа s и p, при этом s <= p. Требуется найти ближайший после s делитель d числа p, такой что:
s <= d p mod d = 0 если s != d, то p mod (s,d] != 0 // в дипазоне от s до d нет делителей
Например, для s = 7 и p = 33, d = 11
Придумал два вот таких варианта:
// тупой перебор int delimeter_1(int s, int p) { if(s <= p) { int d = s; while(0 != p % d) { ++d; } return d; } return p; }
// перебор поумнее int delimeter_2(int s, int p) { if(s <= p) { int q = p / s; while(0 != p % q) { --q; } return p / q; } return p; }
Пояснение. Например для числа 15 построим таблицу:
делители: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 частное : 15 7 5 3 3 2 2 1 1 1 1 1 1 1 1 остаток : 0 1 0 3 0 3 1 7 6 5 4 3 2 1 0
Так вот, в delimeter_1 мы движемся по строке делители, а в delimeter_2 по строке частное - второй вариант получается чуть быстрее.
У меня есть подозрение, что возможно есть более быстрое и элегантное решение, основанное на свойствах чисел, либо вообще без циклов, либо с более короткими циклами. Мне не обязательно готовое решение, может кто-то подскажет где почитать на близкую тему или выскажит интресные мысли и замечания.
Подумав, пришел к выводу, что аналитического неитерационного алгоритма не сущетсвует. Такой алгоритм можно представить в виде некой функции f(q,s) = d, то есть q mod f(q,s) = 0, или в виде уравнения q mod (s + k) = 0, где s + k = d. Как вытащить k мне не известно, перешерстил все и ничего не нашел.


Ответ

Решая перебором, следует комбинировать оба подхода. Для p/d < d применять первый, для p/d > d второй. Т.е. сначала бежим по делителям, потом по частным. В случае с таблицей по 15 будет от 1 до 4 (по делителю) первый подход, от 3 до 1 (по частным) второй.
Для варианта d = 1000 таблица будет из 1000 столбцов, а итераций от 1 до 31 и обратно от 31 до 1 всего 62 (плюс-минус) максимум.
Дальше учитываем s и оптимизируем. Т.к. для первого подхода мы пройдем все делители от s до sqrt(p) второй раз при проходе по частным эти делители проходить не нужно, второй подход можно сразу начинать с s и до 1. Получаем простой цикл от 1 до sqrt(p), просто для выявления ближайшего к s делителя порядок не прямой.
В итоге:
int delimeter_3(int s, int p) { int i = s; while(i > 1) { if(p % i==0) break; if(i >= s) i++ else i--; if(i > sqrt(p)) i = min(s, p / s) - 1; }
return i >= s ? i : i ? p / i : p; }

Выбор индекса объекта в коллекции

Каким образом эффективнее всего найти индекс объекта коллекции, который имеет указанное свойство. Например, нужно найти индекс объекта коллекции, который имеет свойство id равное 123. Сейчас при помощи Underscore делаю так:
_.indexOf(collection, _.findWhere(collection, {id: 123}));
Подскажите, пожалуйста, более красивый и эффективный способ, если таковой имеется.


Ответ

Как в Underscore, так и в Lodash есть метод _.findIndex, который собственно объединяет функционал _.index и _.findWhere и возвращает индекс элемента коллекции по условию:
var collection = [{id: 321}, {id: 123}, {id: 333}];
_.findIndex(collection, {id: 123}); // 1
В дополнение есть метод findLastIndex, который ищет с конца коллекции (в Underscore и Lodash).
Обновление:
В Underscore эти методы появились только с версии 1.8 (в Lodash - с 1.1.0)

Как посмотреть что хранится в php://output?

Делаю проверку и отладку с помощью xDebug. OpenServer + xDebug + phpStorm.
Как посмотреть что хранится в php://output?


Ответ

ob_get_contents() — Возвращает содержимое буфера вывода
Пример использования
ob_start();
echo "Привет ";
$out1 = ob_get_contents();
echo "Мир";
$out2 = ob_get_contents();
ob_end_clean();
var_dump($out1, $out2);
Результат
string(6) "Привет " string(11) "Привет Мир"

Полиморфизм подтипов

Что из себя представляет полиморфизм подтипов в C#? Как его реализовать?


Ответ

Полиморфизм подтипов -- это то, что обычно понимают под полиморфизмом в объектно-ориентированном программировании. Он заключается в том, что вызывающий код использует объект, опираясь только на его интерфейс (контракт), не зная при этом фактического типа. Такой подход позволяет подтипам реализовывать свое поведение и т.о. изменять поведение программы без перекомпиляции кода-клиента. Возьмем пример из Википедии:
public abstract class Animal { public abstract String Talk(); }
public class Cat : Animal { public override String Talk() { return "Meow!"; } }
public class Dog : Animal { public override String Talk() { return "Woof!"; } }
public class Program { private static void Write(Animal animal) { Console.WriteLine(animal.Talk()); }
public static void Main(String args[]) { Write(new Cat()); Write(new Dog()); } }
Здесь класс Animal -- это базовый тип, объявляющий интерфейс (контракт). Интерфейс состоит всего из одного метода. Далее у нас есть два дочерних класса -- Cat и Dog, каждый из которых переопределяет метод Talk своим собственным поведением, соответствующим этому классу.
Метод Program.Write является в данном случае клиентом -- он принимает на вход объект типа Animal и вызывает метод Talk. При этом он не знает ничего о фактическом типе объекта, а пользуется только объявленным интерфейсом. Подсовывая ему экземпляры разных типов -- Cat и Dog -- мы получаем разное поведение (на консоль выводится разный текст).

Как запретить биндить символ знака вопроса в SQL-запросе при использовании PDO в PHP?

В SQL-запросе используется символ знака вопроса - ? и PDO пытается биндить к нему значение ($1), но в данной ситуации это совершенного не нужно, т.к. символ знака вопроса это оператор языка SQL для работы с типом данных JSONB. Как обойти этот механизм присвоения значений?
$statement = "SELECT id FROM public.parameter WHERE variations ?| array[ 'something' ] LIMIT 1 OFFSET 0;"; $sth = $this->pdo->prepare( $statement ); $sth->execute();


Ответ

Вместо таких операторов можно использовать соответствующие функции (jsonb_exists, jsonb_exists_any, jsonb_exists_all). К примеру, если запустить в psql команду \do+ "?", выведется имя функции, которая вызывается оператором ? А можно определить собственный оператор без символов ?, например:
CREATE OPERATOR ~@ (LEFTARG = jsonb, RIGHTARG = text, PROCEDURE = jsonb_exists) CREATE OPERATOR ~@| (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_any) CREATE OPERATOR ~@& (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_all) ...чтобы использовать ~@, ~@| и ~@& вместо ?, ?| и ?& соответственно. Пример:
$sth = $dbh->prepare("SELECT * FROM stuff WHERE meta ~@ :value"); $sth->bindValue(1, $value, PDO::PARAM_STR); $sth->execute();
Это перевод вот этого ответа с английского StackOverflow от пользователя alexius

EntityFramework создает множество записей в бд

Пишу программу для учета поставщиков, и заказов у данных поставщиков с использованием Entity Framework Code First.
Одновременно с созданием заказа, создается новый поставщик с данным заказом, то есть в БД есть поставщик с заказом и поставщик без заказа, если создать ещё один заказ, то создастся ещё один поставщик с данным заказом.
Классы:
Поставщик
public class Contractor { public int ContractorId { get; set; } public string ContractorName { get; set; } public string ManagerName { get; set; } public string ContactPhone { get; set; } public string ContactEmail { get; set; } public ICollection Orders { get; set; } public override string ToString() { return ContractorName; } }
Заказ
public class Order { public int OrderId { get; set; } public virtual ICollection PositionsQty { get; set; } public decimal Sum { get; set; } public string InvoiceNumber { get; set; } public Byte[] InvoiceScan { get; set; } public Byte[] ClosingDocScan { get; set; } public DateTime OrderDate { get; set; } public DateTime DeliveryDate { get; set; } public int ContractorId { get; set; } public virtual Contractor Contractor { get; set; }
public override string ToString() { return "Счет №: " + InvoiceNumber + " от " + OrderDate.Day + "/" + OrderDate.Month + "/" + OrderDate.Year; } }
Создание Заказа
private void SaveBtn_Click(object sender, RoutedEventArgs e) { using (var db = new ContractorContext()) { Order order = new Order(); if(InvoiceNumberBox.Text != null) order.InvoiceNumber = InvoiceNumberBox.Text; order.DeliveryDate = DeliveryDatePick.SelectedDate ?? DateTime.Now; order.OrderDate = OrderDatePick.SelectedDate ?? DateTime.Now; if(InvoiceSumBox.Text != null) order.Sum = Decimal.Parse(InvoiceSumBox.Text.Replace('.',',')); order.Contractor = _contractor; order.ContractorId = _contractor.ContractorId; order.PositionsQty = new List(); foreach (PositionsQty item in OrderPositions.Items) { order.PositionsQty.Add(item); } if (_contractor.Orders != null) { _contractor.Orders.Add(order); } else { _contractor.Orders = new List {order}; } //db.Contractors.AddOrUpdate(_contractor); db.Orders.AddOrUpdate(order); db.SaveChanges(); this.Close(); } }
Объект _contractor передаётся из другой формы.
В чем ошибка?


Ответ

объекты order и _contractor находятся в разных экземплярах контекста ContractorContext. Чтобы не плодить дубли не заполняйте поле order.Contractor, вполне достаточно указать order.ContractorId

RecyclerView в CoordinatorLayout

Есть ли способ сворачивать при скролле RecyclerView другую вьюшку, которая выше RecyclerView? Как это сделать с Toolbar я знаю, но вот что-то не понятно как тоже самое провернуть с другими вьюшками?


Ответ

Вот пример кода. Надо свой View поместить в AppBarLayout. Здесь layoutHeader будет скролиттся при скролле RecyclerView







Обратите внимание на дополнительные атрибуты app:layout_behavior="@string/appbar_scrolling_view_behavior" и app:layout_scrollFlags="scroll|enterAlways"
AppBarLayout рекомендуется располагать ниже остальных элементов. При этом он все равно будет вверху страницы.

Почему в середине raw-строки не может быть четное количество обратных слешей совместно с "(')

Например следующий код не выдаст ошибки:
rs = r'Cat\'s home'
А этот код выдаст:
rs = r'Cat\\'s home'
То же самое, так ошибки не будет:
rs = r'Cat\\\'s home'
А этот код выдаст:
rs = r'Cat\\\\'s home'
И так далее...
Этот факт я запомнил, но почему так получается не понимаю


Ответ

Ответ пользователя @Vitalts дан про обычные строки. В raw строках (строки, предназначенные для регулярных выражениях) правила обработки слешей несколько другие.

Из спецификации языка Питон
Even in a raw literal, quotes can be escaped with a backslash, but the backslash remains in the result; for example, r"\"" is a valid string literal consisting of two characters: a backslash and a double quote; r"\" is not a valid string literal (even a raw string cannot end in an odd number of backslashes). Specifically, a raw literal cannot end in a single backslash (since the backslash would escape the following quote character).
Перевод:
Даже в raw строковых константах, кавычки можно экранировать с помощью слеша, но слеш остаётся в результате, например, r'\'' является верной строковой константой, состоящей из двух символов: слеш и кавычка. r'\'— не является корректной константой (даже raw строки не могут оканчиваться нечётным кол-вом слешей, так как слеш экранирует закрывающую кавычку).
При этом несмотря на то, что слеш экранирует кавычки, он не выкидывается из строки; то же происходит и для последовательности из двух слешэй.

Таким образом, этот ответ все же пересекается с ответом @Vitalts:
r'a\'
EOL while scanning string literal: Строка не закончилась, так как последняя кавычка экранирована и является частью строки.
r'a\\'
Всё хорошо: строка закончилась, так как первый слеш экранирует второй.
r'\\\'
Далее по аналогии...

r'1 \' 2'
Всё ок: кавычка в середине экранирована.
r'1 \\' 2'
Первый слеш экранировал второй, после чего строка закончилась. Теперь 2' уже не относится к строке, отсюда invalid syntax

Не запускается приложение через Android Studio

При попытке запустить приложение в Android Studio на реальном устройстве, приложение не устанавливается! Ну... Сначала устанавливается (антивирус пишет, что приложение проверено), а потом оно пропадает (так и не запустив Activity). Приложение — Hello World. В Eclipse все работало нормально.
Вот вывод в консоль:
Waiting for device. Target device: lenovo-lenovo_a536-0123456789ABCDEF Uploading file local path: D:\Android Aplication\myApplication\DictionaryDemo_3\app\build\outputs\apk\app-debug.apk remote path: /data/local/tmp/com.dictionarydemo_3 Installing com.dictionarydemo_3 DEVICE SHELL COMMAND: pm install -r "/data/local/tmp/com.dictionarydemo_3" WARNING: linker: libvc1dec_sa.ca7.so has text relocations. This is wasting memory and is a security risk. Please fix. WARNING: linker: libvc1dec_sa.ca7.so has text relocations. This is wasting memory and is a security risk. Please fix. pkg: /data/local/tmp/com.dictionarydemo_3 Success
Launching application: com.dictionarydemo_3/com.dictionarydemo_3.MainActivity. DEVICE SHELL COMMAND: am start -n "com.dictionarydemo_3/com.dictionarydemo_3.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER WARNING: linker: libvc1dec_sa.ca7.so has text relocations. This is wasting memory and is a security risk. Please fix. WARNING: linker: libvc1dec_sa.ca7.so has text relocations. This is wasting memory and is a security risk. Please fix. Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.dictionarydemo_3/.MainActivity } java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.dictionarydemo_3/.MainActivity } from null (pid=4359, uid=2000) not exported from uid 10187 at android.os.Parcel.readException(Parcel.java:1465) at android.os.Parcel.readException(Parcel.java:1419) at android.app.ActivityManagerProxy.startActivityAsUser(ActivityManagerNative.java:2228) at com.android.commands.am.Am.runStart(Am.java:680) at com.android.commands.am.Am.onRun(Am.java:270) at com.android.internal.os.BaseCommand.run(BaseCommand.java:47) at com.android.commands.am.Am.main(Am.java:76) at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method) at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:243) at dalvik.system.NativeStart.main(Native Method)
Как исправить?


Ответ

Нужно было добавить в код Activity (в файле Manifest.xml):

WPF DateTime Format

Есть TextBox текстовое поле которого биндится к полю типа DateTime. Сейчас форматирование заданно следующим образом:
Text="{Binding Date, Mode=OneWay, StringFormat=\{0:D\},ConverterCulture=ru}"
Выводит он соответственно примерно следующее: 12 ноября 2015г
А нужно чтобы он выводил следующее: 12 ноября 2015г (четверг)
Как этого добиться?


Ответ

В результате вышло так:
Text="{Binding DateOfProduction, Mode=OneWay, StringFormat=\{0:D\} ({0:dddd}), ConverterCulture=ru}"

Передача изображения из нативной библиотеки в Android

Подскажите, как передать изображение из библиотеки на C++ в приложение под андроидом.
Пишу простой html рендер: https://www.livecoding.tv/video/simple-html-render-c/ . Во второй части хочу запустить его под андроидом.
Самый простой вариант передачи изображения:
String img = Render("index.html"); Bitmap bitmap = getBitmap(img);
Через файл. Но это костыль и так делать не надо.
Как реализовать передачу изображения?
На мой взгляд самым простым способом будет возвращать само изображение, а не ссылку на него. Как его загрузить в Bitmap?
Не самым простым способом будет формирование изображение из C++. Есть пример вызова Bitmap.createBitmap() - https://stackoverflow.com/questions/7677092/creating-an-android-graphics-bitmap-from-c , но это недостаточно для решения.


Ответ

Верните из JNI массив байтов, а потом грузите на стороне Java картинку из этого массива, как хотите.
JNIEXPORT jbyteArray JNICALL get_bitmap(JNIEnv *env, jobject obj, jstring str) { const char *nativeString = env->GetStringUTFChars(str, 0); // "index.html" char* data = ;//указатель на данные, берите их откуда хотите size_t size = ; // размер данных
jbyteArray result = env->NewByteArray(size);
if (result == NULL) { return NULL; // out of memory error thrown }
env->SetByteArrayRegion(result, 0, size, data); return result; }
// Регистрация нативных методов в JVM static JNINativeMethod methods[] = { {"getBitmap", "(Ljava/lang/String;)[B", (void *)get_bitmap}, };
jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { JNIEnv *env; if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_4) != JNI_OK) return JNI_FALSE;
jclass clazz = env->FindClass("com/example/MyCoolClass"); if (clazz ) { if (env->RegisterNatives(clazz, methods, sizeof(methods)/sizeof(methods[0])) < 0) return JNI_FALSE; }
return JNI_VERSION_1_4; }
На стороне Java:
package com.example;
class MyCoolClass { public static void main(String[] args) { String img = Render("index.html"); byte[] bytes = getBitmap(img); Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); } private static native byte[] getBitmap(String arg); }
Надеюсь, идея вам понятна. Если вопрос производительности для вас критичен, почитайте это

Проверка валидности покупки в Google Play

После покупки получаем JSON
{ "packageName":"*****", "productId":"test2", "purchaseTime":1449140071159, "purchaseState":0, "developerPayload":"subs:*****", "purchaseToken":"*******", "autoRenewing":false }
Стандартно можем проверить его на андроид устройстве на валидность (т.е. не подделка ли покупка). Данным методом:
public boolean isValid(TransactionDetails transactionDetails);
используется библиотека https://github.com/anjlab/android-inapp-billing-v3
А необходимо проверять валидность покупки на стороне нашего сервера. т.е. отправить туда полученный JSON и уже там проверить на валидность.. Как это можно реализовать? Серверная часть пишется на c#
UP#1 Все работает.. один момент при отправке Сигнатуры его надо Энкодить
URLEncoder.encode(_base64Signature, "UTF-8")


Ответ

Когда приходит результат покупки, то в поле inapp_signed_data у Intent'а будет сигнатура.
Теперь вам нужен RSA. Для C# вам надо его сгенерировать из публичного ключа из вашей консоли разработчика в GP:
const string MY_BASE64_PUBLIC_KEY = "Ваш base64 Google публичный ключ"; RSACryptoServiceProvider provider = PEMKeyLoader.CryptoServiceProviderFromPublicKeyInfo(MY_BASE64_PUBLIC_KEY); string xmlPublicKey = provider.ToXmlString(false);
Вот класс для этого:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Security.Cryptography; using System.IO;
namespace PublicKeyConvert { public class PEMKeyLoader {
// encoded OID sequence for PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1" static byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
private static bool CompareBytearrays(byte[] a, byte[] b) { if (a.Length != b.Length) return false; int i = 0; foreach (byte c in a) { if (c != b[i]) return false; i++; } return true; }
public static RSACryptoServiceProvider CryptoServiceProviderFromPublicKeyInfo(byte[] x509key) { byte[] seq = new byte[15]; int x509size;
if (x509key == null || x509key.Length == 0) return null;
x509size = x509key.Length;
// --------- Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob ------ MemoryStream mem = new MemoryStream(x509key); BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading byte bt = 0; ushort twobytes = 0;
try { twobytes = binr.ReadUInt16(); if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81) binr.ReadByte(); //advance 1 byte else if (twobytes == 0x8230) binr.ReadInt16(); //advance 2 bytes else return null;
seq = binr.ReadBytes(15); //read the Sequence OID if (!CompareBytearrays(seq, SeqOID)) //make sure Sequence for OID is correct return null;
twobytes = binr.ReadUInt16(); if (twobytes == 0x8103) //data read as little endian order (actual data order for Bit String is 03 81) binr.ReadByte(); //advance 1 byte else if (twobytes == 0x8203) binr.ReadInt16(); //advance 2 bytes else return null;
bt = binr.ReadByte(); if (bt != 0x00) //expect null byte next return null;
twobytes = binr.ReadUInt16(); if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81) binr.ReadByte(); //advance 1 byte else if (twobytes == 0x8230) binr.ReadInt16(); //advance 2 bytes else return null;
twobytes = binr.ReadUInt16(); byte lowbyte = 0x00; byte highbyte = 0x00;
if (twobytes == 0x8102) //data read as little endian order (actual data order for Integer is 02 81) lowbyte = binr.ReadByte(); // read next bytes which is bytes in modulus else if (twobytes == 0x8202) { highbyte = binr.ReadByte(); //advance 2 bytes lowbyte = binr.ReadByte(); } else return null; byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; //reverse byte order since asn.1 key uses big endian order int modsize = BitConverter.ToInt32(modint, 0);
int firstbyte = binr.PeekChar(); if (firstbyte == 0x00) { //if first byte (highest order) of modulus is zero, don't include it binr.ReadByte(); //skip this null byte modsize -= 1; //reduce modulus buffer size by 1 }
byte[] modulus = binr.ReadBytes(modsize); //read the modulus bytes
if (binr.ReadByte() != 0x02) //expect an Integer for the exponent data return null; int expbytes = (int)binr.ReadByte(); // should only need one byte for actual exponent data (for all useful values) byte[] exponent = binr.ReadBytes(expbytes);
// ------- create RSACryptoServiceProvider instance and initialize with public key ----- RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); RSAParameters RSAKeyInfo = new RSAParameters(); RSAKeyInfo.Modulus = modulus; RSAKeyInfo.Exponent = exponent; RSA.ImportParameters(RSAKeyInfo);
return RSA; } finally { binr.Close(); } }
public static RSACryptoServiceProvider CryptoServiceProviderFromPublicKeyInfo(String base64EncodedKey) { try { //see if the file is a valid Base64 encoded cert return CryptoServiceProviderFromPublicKeyInfo(Convert.FromBase64String(base64EncodedKey)); } catch (System.FormatException) { }
return null; }
public static byte[] X509KeyFromFile(String filename) { byte[] x509key;
if (String.IsNullOrWhiteSpace(filename) || !File.Exists(filename)) return null;
StreamReader sr = File.OpenText(filename); String filestr = sr.ReadToEnd(); sr.Close(); StringBuilder sb = new StringBuilder(filestr); sb.Replace("-----BEGIN PUBLIC KEY-----", ""); //remove headers/footers, if present sb.Replace("-----END PUBLIC KEY-----", "");
try { //see if the file is a valid Base64 encoded cert x509key = Convert.FromBase64String(sb.ToString()); } catch (System.FormatException) { //if not a b64-encoded publiccert, assume it's binary Stream stream = new FileStream(filename, FileMode.Open); int datalen = (int)stream.Length; x509key = new byte[datalen]; stream.Read(x509key, 0, datalen); stream.Close(); }
return x509key; }
} }
Теперь можно проверять подпись сообщения:
public static bool Verify(string message, string base64Signature, string xmlPublicKey){ // Create the provider and load the KEY RSACryptoServiceProvider provider = new RSACryptoServiceProvider(); provider.FromXmlString(xmlPublicKey);
// The signature is supposed to be encoded in base64 and the SHA1 checksum // of the message is computed against the UTF-8 representation of the message byte[] signature = System.Convert.FromBase64String(base64Signature); SHA1Managed sha = new SHA1Managed(); byte[] data = System.Text.Encoding.UTF8.GetBytes(message);
return provider.VerifyData(data, sha, signature); }
message - это ваш JSON.

Включение поддержки стандарта с++11 в Qt

Я понимаю, как включить поддержку 11 стандарта С++ в каждом отдельном проекте Qt. В .pro файле пишем:
CONFIG += C++11
и все работает.
Можно ли настроить Qt Creator, чтобы он автоматически добавлял эту строчку в файл проекта? Т.е. каждый вновь создаваемый проект должен сразу создаваться с этой опцией. Гугл как-то не очень помогает...


Ответ

В папке Qt Creator'а есть каталог
share\qtcreator\templates\wizards\projects
В нём - папки, имя которых соответствует типу создаваемого проекта. Внутри папки лежит файлик file.pro. Этот файл - шаблон для нового проекта.

Полиморфизм в реляционных БД. Возможно ли?

Есть база данных (postgresql), содержащая три таблицы - Люди (ID, Имя, Фамилия, Отчество, Наименование), Организации (ID, Наименование, Адрес, Расчетный счет), Автомобили (ID, Марка, Модель, Пробег, Владелец). Суть проблемы: Необходимо создать связи между автомобилями и владельцами. Владельцем автомобиля может быть как человек (запись в таблице Люди), так и организация (запись в таблице Организации). Вопрос: Каким образом можно осуществить данную связь? Может ли внешний ключ быть полиморфным и, следовательно, каким образом во время JOIN узнать с какой таблицей объединятся(как хранить информацию о типе во внешнем ключе)? PS: Заранее извиняюсь за, возможно, глупый вопрос, и прошу учесть, тот факт, что с SQL и РБД как таковыми только познакомился, и есть острая необходимость решить вышеуказанную проблему в крайне короткий срок. Update: В первой версии вопроса не указал общее поле - Наименование - в случае если Владелец - человек, его Наименование - например, Иванов И.И. В качестве примера приведу вымышленный код, думаю так будет понятней:
SELECT Авто.Марка, Авто.Модель, Наименование FROM Авто INNER JOIN Авто.Внешний_ключ_владельца.Таблица ON Авто.Внешний_ключ_владельца.ID = Авто.Владелец.ID
И возможный результат: "Daewoo" "Nexia" "Иванов. И.И." "Ford" "Focus" "ООО ТОРГОПТ" "Schevrolet" "Camaro" "Сидоров С.В."


Ответ

Структура данных должна быть такой, чтобы запросы по ней были максимально простыми. Если вам в вашем запросе нужно только Наименование от владельца, то в разделении людей и организаций нет никакого смысла. Это должна быть одна таблица Владельцы. Дополнительные поля могут быть как в той же таблице, так и в дочерних типа "данные юрлиц"/"данные физлиц". Все зависит от запросов, сравните ваш вариант:
select cars.*, persons.fullname from cars join persons on cars.owner = persons.id and cars.isorg = 0 union all select cars.*, orgs.fullname from cars join orgs on cars.owner = orgs.id and cars.isorg = 1
и запрос с одной таблицей:
select cars.*, owners.fullname from cars join owners on cars.owner = owners.id
Если вам понадобятся все дополнительные поля в этом запросе (надо еще придумать как их красиво выводить в одной таблице) вы получите одни и те же данные: будут null для людей в адресе и расчетном счете, и null для фио для организаций.
Если вы планируете более сложную логику запросов (которую вы в вопросе не указали) то идите от нее. И идите путем простоты.

Рекурсивные запросы, списки смежности

есть таблица хранящая вершины в виде списков смежностей
Keyword(id INT PRIMARY KEY, value TEXT, parent_id INT REFERENCES Keyword DEFAULT NULL);
нужно посчитать для каждой вершины размер ее поддерева т.е. для данных
id parent_id ------------- 0 NULL 1 0 2 0 3 1 4 1
будет
id size ------------- 0 5 1 3 2 1 3 1 4 1
по идеи можно пройти по списку смежности, с использованием массива, который хранит путь потом используя операнды @> или <@ посчитать размер поддерева.
Т.е. есть пути 0-1-3, 1-3, 0-8, 0-1-4, 1-4
и для 0 размер будет 5
не пойму как для каждого узла хранить масив определяющий путь без использования функций


Ответ

WITH RECURSIVE q AS ( select id,id as idx from Keyword union all select K.id,q.idx as idx from Keyword K, q where K.parent_id=q.id ) select idx,count(1) from q group by idx order by idx
Вот так в postresql выглядят рекурсивные запросы. Внутри RECURSIVE всегда должен быть union. Первая часть union должна выбрать стартовые записи, с которых рекурсия начнется. Например, если бы нам надо было посчитать не количество потомков, а получить всех потомков записи с id=0 мы бы в первой части задали условие where id=0. Вторая часть union это основная рекурсивная часть. Она осуществляет спуск по дереву, выбирая записи из with и при этом поставляя собственные выбранные записи в этот же with, после чего она их там видит и использует уже их id. Что бы правильно посчитать записи нам надо знать изначальный id с которого начала выбираться ветвь, для этого приходится в первом подзапросе выбрать id второй раз и назвать его по другому, потому как просто q.id равен parent.id и у потомка это будет id его непосредственного родителя. А выбрав id под другим именем, не указанным в where мы получаем именно изначального родителя.

Как удалить произвольный элемента стека Forth

Как удалить произвольный элемент из стека данных в языке Форт?


Ответ

N ROLL DROP
где N — номер элемента от вершины стека начиная с 0.
Например, фраза 4 3 2 1 0 3 ROLL DROP оставит на стеке 4 2 1 0
Такой вариант слова ROLL закреплен в спецификации начиная с Forth-83

слушатель на checkbox из listview не работает

Создал listView с собственной разметкой, привязал к SimplApdapter А в разметке есть checkbox,и мне нужно поставить на него слушатель.Я испробовал все, не получается.Как решить данную проблему?
ListView listView = (ListView) findViewById(R.id.listView); list = new ArrayList

Ответ

Вы не можете просто так повешать слушатели на вложенные в айтемы списка виджеты из активити.
Для реализации слушателей такого рода, вам нужно либо создать кастомный адаптер на основе одного из стандартных и в нем при биндинге на айтем (метод getView() адаптера) прикреплять слушатель на вложенные View, либо использовать стандартные возможности системы - режим CHOICE_MODE_MULTIPLE для списка.
Кроме того, у вас появится проблема сохранения чекнутости элементов при прокрутке.
Подробности реализации вариантов списка с чекбоксами смотрите этот ответ

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

Можно ли как-то программно заставить роутер переподключиться?
WAN-соединение (динамический ip-адрес). хочу иметь возможность, запустив скрипт, получить от провайдера новый ip-адрес. хотелось бы увидеть код на любом языке.


Ответ

Это можно сделать разными способами.
Через HTTP. Отловите запросы, которые делает ваш браузер когда вы заставляете роутер получить новый IP вручную - и воспроизведите их в скрипте. Желательны знания протокола HTTP. Отловить эти запросы можно через инструменты разработчика в браузере или через Fiddler Через telnet или ssh. Подключитесь к роутеру по этим протоколам и попробуйте найти нужную команду. В скрипте достаточно послать ее еще раз. Обычно скрипты для такого способа выходят проще - но поиск решения сложнее из-за отсутствия документации. Желательны знания UNIX. Для подключения можно воспользоваться Putty Через UPnP. Винда же как-то умеет интернет отцеплять и подцеплять обратно - значит, и для вас способ должен быть. Но тут подробностей я вообще не знаю. Нужны знания UPnP, которых у меня нет.
Более конкретных советов дать не могу: разные роутеры очень сильно отличаются друг от друга, единых стандартов нет (кроме UPnP). Даже одна и та же модель роутера, выпущенная в разные годы, может работать по-разному.

Предоставляет ли провайдер VPN-доступ? Если да, то можно отказаться от интернета по DHCP, подключить себе VPN - а переподключать VPN скриптом куда проще.
Еще один альтернативный вариант - TOR. Видимый IP-адрес будет меняться при каждой смене выходной ноды. Возможно, клиент можно и как-нибудь пнуть для принудительного изменения выходной ноды (перезапуск клиента - универсальный способ). Для использования этого варианта понадобится научиться работать через прокси-сервер.

Отклик на касание по cardview

Есть список кликабельных CardView построенных с помощью RecyclerView и кастомного Адаптера со стандартной реализацией. ViewHolder имплементирует OnClickListener. Отсутствует анимация "касания" элемента. Т.е. при нажатии на любое cardView нет никакого отклика, что нажатие действительно произошло, срабатывает только лишь один OnClickListener.
Как можно прикрутить анимацию ripple эффекта? Вероятно есть уже готовые реализации от самого гугла, но найти ничего не получается почему-то, кроме такого. Попробовал сделать, анимация действительно появилась, но теперь не работает метод OnClickListener :) Вернее, работает, но только если нажимать на края cardview (видимо там где у меня определен layout_margin и куда анимация нажатия не достает). Как можно решить проблему? Спасибо
разметка cardview.xml


Ответ

Видимо это особенности разработки под Android, которые нужно просто знать.
Убрал из разметки android:clickable="true" и все заработало как нужно. Надеюсь кому-нибудь поможет в будущем.

Моя реализация долго выполняющейся задачи с прогрессом и ее слабые места

Ситуация: имеется приложение asp.net mvc. Есть кнопка по нажатии на которую запускается процесс генерации некоего отчета. Отчет может генерироваться довольно долго например несколько минут. Необходимо также после запуска генерации показать пользователю модальное окно с прогрессом выполнения генерации и возможностью отмены. Я реализовал это так.
private static readonly IList DownloadStates = new List();
public ActionResult Export() { var task = new DownloadTask(Guid.NewGuid()); DownloadStates.Add(task);
string zipFilename = string.Format("{0}.zip", task.Id); GenerateAsync(zipFilename, task);
return Json(task.Id, JsonRequestBehavior.AllowGet); }
Этот экшен вызывается при нажатии на кнопку генерации отчета. Тут происходит вот что. Сначала создается задача task. Код этого класса выглядит так
public class DownloadTask { public DownloadTask() { }
public DownloadTask(Guid id) { Id = id; State = DownloadState.NotStarted; CancellationTokenSource = new CancellationTokenSource(); }
public Guid Id { get; set; }
public double CurrentProgress { get; set; }
// состояние задачи - запущена, отменена, ошибка, завершена и тд public DownloadState State { get; set; } }
Задача помещается в коллекцию DownloadStates.
Вот так выглядит код асинхронного метода GenerateAsync
public async Task GenerateAsync(string filename, DownloadTask currentTask) { await Task.Factory.StartNew(() => { try { currentTask.State = DownloadState.Processing;
foreach (var page in pages) { // обновление прогресса currentTask.CurrentProgress = // ... // обработка данных } currentTask.State = DownloadState.Completed; } catch { currentTask.State = DownloadState.Faulted; // обработка ошибки } }).ConfigureAwait(false); return currentTask.Id; }
То есть нажав на кнопку мы отправляем запрос на генерацию отчета. Создается задача, ей присваивается уникальный Guid, задача помещается в коллекцию задач DownloadStates и после этого запускается асинхронный метод GenerateAsync. После запуска этого метода сервер отправляет в виде ответа клиенту guid созданной задачи. Асинхронный метод что важно запускается без await по принципу fire and forget. Дальнейшая связь с ним процессом генерации происходит через коллекцию DownloadStates.
После этого на клиенте когда пришел ответ сервера с идентификатором задачи запускается функция setInterval в которой каждые 200 мс выполняется запрос к серверу чтобы узнать прогресс выполнения задачи и отобразить этот прогресс в модальном окне. Вот код экшена отвечающего за получение текущего прогресса
public ActionResult Progress(Guid taskId) { var task = DownloadStates.FirstOrDefault(x => x.Id == taskId); string state = ""; bool isFaulted = false; bool isCancelled = false;
if (task != null) { switch (task.State) { case DownloadState.Faulted: isFaulted = true; DownloadStates.Remove(task); break; case DownloadState.Processing: state = "processing"; break; // ... прочие ветки } } else isFaulted = true;
return Json(new { progress = task != null && task.State != DownloadState.Completed ? task.CurrentProgress * 100 : 100, text = state, isFaulted, isCancelled }, JsonRequestBehavior.AllowGet); }
Здесь происходит следующее: если задача выполняется то в ответе возвращаем клиенту текущий прогресс (он хранится в таске в коллекции DownloadStates а обновляется внутри асинхронного метода). Если во время выполнения асинхронного метода произошло какое-то исключение, то клиенту возвращается isFaulted = true и клиент получив это значение останавливает таймер и прекращает слать запросы о прогрессе (задача завершилась с ошибкой) и отображает сообщение об ошибке. Если же задача имеет статус Completed то прогресс устанавливается в 100% и таймер на клиенте также останавливается после чего выполняется запрос на загрузку сформированного отчета.
Вкратце это работает вот так как я описал. Эта схема действительно работает но у меня нет большого опыта с написанием подобного асинхронного кода и поэтому меня мучают сомнения правильно ли я все сделал? Например при вызове асинхронного метода GenerateAsync я не вызываю await чтобы не дожидаться его завершения а сразу вернуть клиенту идентификатор новой задачи. Поэтому узнать об ошибке я могу только через установку свойства isFaulted у моих задач в коллекции, хранящейся в контроллере и чтение этого свойства при получении текущего прогресса.
Хотелось бы услышать мнение более опытных программистов насчет потенциальных проблем моего кода (утечки памяти, незавершенные таски, необработанные исключения, может быть где-то надо было поставить lock или могут возникнуть блокировки или что-то еще?). Есть ли тут какие-то слабые места (а они я уверен есть), что тут стоило бы улучшить особенно с учетом многопоточного выполнения и потенциального запуска нескольких задач одновременно. Заранее спасибо!
P.S. к сожалению использование SignalR оказалось невозможным по независящим от меня причинам поэтому вариант переделать все на SignalR я рассматривать не могу


Ответ

Основные проблемы
Нет lock на обращениях к DownloadStates. Класс List не потокобезопасен, доступ к нему нужно вручную синхронизировать. Task.Factory.StartNew не обязательно запускает таск в новом потоке. Вместо него стоит использоватьTask.Factory.Run Единственный более-менее надежный метод выполнения фоновых задач в ASP.NET - это QueueBackgroundWorkItem Ваш подход не слишком применим в живых приложениях, при наличии двух и более web-серверов, и, соответственно, двух копий приложения.
Гораздо надежнее не запускать фоновые задачи в самом ASP.NET, а положить задания в базу данных, и сделать win-сервис, который будет их оттуда доставать, выполнять, и отчитываться через базу о прогрессе.

Подробнее:
Синхронизация списков
List работает на простых массивах внутри. Т.е. поиск FirstOrDefault в нем сделан обычным перебором элементов по индексу от 0 до N-1.
Предположим у вас запустилось два таска - 0 и 1.
Таск 0 выполнился. Пришел запрос на Progress для Task 0. Дошел до строчки с Remove Пришел запрос на Progress для Task 1. Зашел в поиск FirstOrDefault, дошел до индекса 1 Запрос на Progress для Task 0 взял и удалил свой элемент из списка! В Progress для Task 1 вызов FirstOrDefault... падает? возвращает null?
QueueBackgroundWorkItem
В ASP.NET есть механизм рейсайкла апппула. В определенный момент IIS может взять и перезапустить процесс, в котором выполняется приложение. По умолчанию это происходит раз в 29 часов. Может происходить по лимиту памяти. Или по неактивности. Обычный таск из Thread Pool или любой другой фоновый поток будет просто прибит при ресайкле, мгновенно и без каких-либо уведомлений.
Таск, созданный через QueueBackgroundWorkItem, получит уведомление о выключении (через CancellationToken). Кроме того, у него будет 90 секунд чтобы на это уведомление отреагировать. Не сверхнадежно, но лучше чем ничего.
Проблемы с двумя Web-серверами
Если у вас два бэкенда - то у вас две независимых копии приложения. Два списка DownloadStates. Если запрос о старте таска пришел на один сервер, а запрос прогресса - на другой - то пользователь получит isFaulted.
Решается переносом очереди закачек в базу или в любое другое общее хранилище (например, сервис с очередью).

Опкод команды mov/xor

В листинге дизассемблированного файла имею:
.text:00401296 cmp eax, 0 .text:00401299 jz short loc_4012B0
Пронзив исполняемый файл hex-редактором, лечу на адрес 696 (адрес первой команды cmp) и там смотрю такие байты:
83 F8 00
Пытаюсь разобраться.. Топаю на http://sparksandflames.com/files/x86InstructionChart.html Там мне подсказывают, что
83 - SUB Ev Ib...
Вычитание? Не сравнение? В самой программе он работает как сравнение.. Привычный мир рушится...
Вопросы:
Почему 83 - вычитание, а не сравнение или опкод "модифицируется" каким-то спец. байтом? Как вычислить опкод команды mov eax,eax (не 89 F8 00 случаем?).
Как в этом случае будет влиять на ход программы байт mod r/m? Или xor eax,eax? (не 35 F8 F8 случаем?)
Видимо, просто запутался очень + не хватает знаний и нормально изложенного материала. Направьте, камрады.


Ответ

Команда целиком состоит из трех байт: 83 F8 00
83h - это только часть опкода. Как уже заметил VladD, это может соответствовать командам ADD, OR, ADC, SBB, AND, SUB, XOR и CMP. Чтобы понять, что это за команда фактически, нужно смотреть следующий байт (F8h). Это байт MOD R/M, состоящих из 3 полей (по 2, 3, 3 бита):
F8 == 11 111 000
По второму полю этого байта можно определить конкретную команду (хотя, обычно оно отвечает за один из операндов) - как раз из списка ADD, OR, ADC, SBB, AND, SUB, XOR и CMP. Первое поле показывает, что второй (на самом деле первый) операнд - это регистр (или адрес в памяти, но в данном случае это все же регистр). 000 - это, собственно, код регистра, EAX.
Третий байт является вторым операндом команды - 0.
Больше по этой теме можно почитать, например, здесь: Крис Касперски - Дизассемблирование в уме
А еще лучше - читать руководства от Intel в оригинале
Используемый вами справочник очень не полный.
Как вычислить опкод команды mov eax,eax?
Скомпилировать и посмотреть, это наиболее надежный способ, или смотреть в руководстве от Intel.
Или xor eax,eax? (не 35 F8 F8 случаем?)
Скорее 31 C0. Второй байт - байт mod r/m, там просто указывается, что производится операция производится между регистром и регистром, и коды самих регистров:
11 000 000
(000 в обоих случаях - обозначение регистра eax). А первый байт - не 35h, а 31h, т.к. операция не между регистром/памятью и значением, а между регистром и регистром/памятью.

Решение уравнений высших степений

Прошу подсказать алгоритм для поиска корней уравнения высшей степени. Конкретней: есть многочлен вида k[0] * x^n + k[1] * x ^ (n - 1) + ... + k[n - 1] k[i] принадлежит Z и |k[i]| <= 10^9.Известно, что все корни целые.


Ответ

Все целые корни многочлена с целыми коэффициентами являются делителями его свободного члена. Поэтому есть такой путь: 1. Провести факторизацию свободного члена. 2. Найти все делители свободного члена как произведения его простых множителей (взятых в степенях не выше, чем в каноническом разложении), со знаками плюс и минус. 3. Отобрать все корни среди делителей.
На самом деле главная проблема - в нахождении одного корня x=a, поскольку в соответствии с теоремой Безу многочлен разделится на x-a, и следующий корень можно будет подставлять в частное. При этом повторная факторизация также получается путём несложного пересчёта.

android Как узнать, что приложения удаляют?

android Как узнать, что приложения удаляют? и перед удалением выполнить действия по очистке данных


Ответ

Cоздайте класс, унаследуйте его от BroadcastReceiver, и в манифесте объявите его таким образом:

Далее перекройте onReceive, в котором опишите Вашу логику при удалении приложения
@Override public void onReceive(Context context, Intent intent) { if (intent.getDataString().equals("package:your.package.name")) { //methods } }

Варианты реализации lock-free алгоритма

Допустим, есть класс:
class LockFree { LockFree(int num) : n(num) {} int next() {n += 1; return n;} private: int n; };
Какие есть стандартные методы организовать lock-free доступ к n? То есть, интересует lock-free (без мьютексов) реализация функции next(), которую можно было бы использовать в многопоточной многоядерной системе.
Было бы круто узнать как о возможностях современного стандарта (вероятно это std::atomic + варианты compare_exchange), так и о самопальных велосипедах, которые можно было бы использовать в plain c.


Ответ

Самый простой метод:
class LockFree { LockFree(int num) : n(num) {} int next() {return ++n;} private: std::atomic n; };
Это покроет все Ваши нужды в 99% случаев.

а если next() будет вида next() { return n + n^2 + n^3; }
Тогда будет так:
int next() { int oldN = n; while(true) { int newN = oldN + oldN*oldN + oldN*oldN*oldN; if(n.compare_exchange_strong(oldN, newN)) return newN; } }

Как одновременно перехватывать касания в onTouch методе и двойной клик для RelativeLayout?

Как одновременно перехватывать касания в onTouch методе и двойной клик для RelativeLayout??


Ответ

Попробуйте так:
activity_main.xml

MainActivity.class
public class MainActivity extends AppCompatActivity {
private GestureDetectorCompat DoubleTap; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RelativeLayout main_layout = (RelativeLayout) findViewById(R.id.main_layout);
DoubleTap = new GestureDetectorCompat(this, new MyGestureListener()); main_layout.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (MotionEvent.ACTION_DOWN == event.getAction()){ Log.d("...", "onTouch сработал"); } return DoubleTap.onTouchEvent(event); } }); }
private class MyGestureListener extends GestureDetector.SimpleOnGestureListener { @Override public boolean onDown(MotionEvent e) { return true; } @Override public boolean onDoubleTap(MotionEvent e) { Log.d("...", "DoubleTap сработал"); return false; } } }

Как передать/получить данные в/из диалогового фрагмента DatePicker

Есть диалоговый фрагмент:
public class SelectDateFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // устанавливаем дату, которая отображается в диалоговом окне Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(getActivity().date_choice_millis); int yy = calendar.get(Calendar.YEAR); int mm = calendar.get(Calendar.MONTH); int dd = calendar.get(Calendar.DAY_OF_MONTH); return new DatePickerDialog(getActivity(), this, yy, mm, dd); } public void onDateSet(DatePicker view, int yy, int mm, int dd) { // получаем выбранную в диалоговом окне дату и сохраняем ее Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.DAY_OF_MONTH, dd); calendar.set(Calendar.MONTH, mm); calendar.set(Calendar.YEAR, yy); getActivity().date_choice_millis = calendar.getTimeInMillis(); } }
И несколько Окон (Activity), обращающихся к нему. В каждом Окне есть метод, вызывающий диалоговый фрагмент:
public void onclick_date_view (View view) { DialogFragment newFragment = new SelectDateFragment(); newFragment.show(getSupportFragmentManager(), "DatePicker");
действия после выбора новой даты ...// Возможно, действия после обновления должны происходить в другом месте? }
Конструкция getActivity().date_choice_millis (переменная из вызвавшего класса) не работает. Как получить и передать данные из/в вызвавшее Окно?


Ответ

Пример из моего проекта - передача из фрагмента в DatePicker и возврат результата в фрагмент. Способ корректно переносит повороты устройства и тп. бедствия:
UPD: в связи с исключением метода getCalendarView() из Material-стиля календаря переписал получение введенной даты из переданных в колбэк параметров
Класс Date Picker:
public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener{
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { Long mDate = getArguments().getLong("date"); final Calendar c = Calendar.getInstance(); c.setTimeInMillis(mDate); int year = c.get(Calendar.YEAR); int month = c.get(Calendar.MONTH); int day = c.get(Calendar.DAY_OF_MONTH);
return new DatePickerDialog(getActivity(), this, year, month, day); }
@Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
Calendar с = Calendar.getInstance(); с.set(year,monthOfYear,dayOfMonth); long date = c.getTimeInMillis(); Intent i = new Intent(); i.putExtra ("date" , date); getTargetFragment().onActivityResult(getTargetRequestCode() , Activity.RESULT_OK , i);
} }
Часть фрагмента, в котором по нажатию на поле TextView (vDate) появляется Date Picker, получение результата, а так же вывод полученной даты в поле TextView, по которому кликали:
public class EditTransactionFragment extends Fragment {

private final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM); private TextView vDate; private final int CHANGE_DATE = 2; Transaction mTransaction;
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setRetainInstance(true); if (mTransaction == null) mTransaction = new Transaction(); }
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { long mDate;
View view = inflater.inflate(R.layout.edit_transaction, null);
mDate = mTransaction.getDate(); vDate = (TextView) view.findViewById(R.id.tr_date); vDate.setOnClickListener(new DateClickListener(mDate)); setTextDate(mDate); return view; }
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data);
if (data == null || resultCode != Activity.RESULT_OK) return;
switch (requestCode) { case CHANGE_DATE: Long date = data.getLongExtra("date", 0); mTransaction.setDate(date); setTextDate(date); return; } }
private void setTextDate(Long date) { vDate.setText(dateFormat.format(date)); }
private class DateClickListener implements View.OnClickListener { private long mDate;
public DateClickListener(long date) { mDate = date; }
@Override public void onClick(View v) { DialogFragment changeDate = new DatePickerFragment(); Bundle args = new Bundle(1); args.putLong("date", mDate); changeDate.setArguments(args); changeDate.setTargetFragment(EditTransactionFragment.this, CHANGE_DATE); changeDate.show(getFragmentManager(), "changeDate"); } } }

Модификаторы доступа в Java

Чем отличаются эти два класса, и какого типа будет класс во втором случае?
public class Man { int age; string name; Man (int age, string name) { this.age = age; this.name = name; } }
и
class Man { int age; string name; public Man (int age, string name) { this.age = age; this.name = name; } }


Ответ

Есть, по умолчанию - доступ из пакета (т.е. из этого пакета доступен, с другого нет).
Public доступен из любого другого класса. Если по нормальному всё делать, то в .java файле ровно 1 public класс и название файла совпадает с названием класса.

Как должен работать %n?

На Хабре говорится
Спецификатор "%n" не учитывает количество символов, выведенных с помощью таких спецификаторов, как "%f". Поэтому, перед "%n" поставим один пробел, чтобы записать в isOkPassword значение 1.
Однако, проверка показывает, что это вовсе не так:
#include
int main(void) { int n;
printf("%f %n
", 12.0, &n); printf("%d", n);
return 0; }

12.000000 10
А как на самом деле должен работать этот код? Вроде %n для того и нужен, чтобы учитывать форматы, ведь иначе в нём не было бы смысла.


Ответ

Спецификатор %n приводит к записи в аргумент-приемник общего количества символов посланных к этому моменту в выходной поток ("...the number of characters written to the output stream so far by this call to fprintf."). Никакого "не учитывания" каких-то спецификаторов формата в нем нет и быть не может.

выборка из 3 таблиц с объединением данных

Добрый вечер, имеется проблема, которую никак не могу решить. Существует 3 таблицы:
tm_posts - данные о постах и страницах tm_attributes - данные о тегах и категориях tm_relationships - связи 1 и 2 таблицы
Пример структуры:
tm_posts:
id | name | text ------------------- 1 | kols | <ТЕКСТ> 2 | ando | <ТЕКСТ> 3 | krot | <ТЕКСТ>
tm_attributes:
id | sign | attr_name ------------------- 1 | tag | учебник 2 | tag | дождь 3 | cat | личное 4 | cat | опыт
tm_relationships:
id | id_attr | id_post ------------------- 1 | 1 | 2 2 | 2 | 2 3 | 3 | 2 4 | 4 | 2
Мне нужно получить такой результат по нику ando:
id | name | text | tags | category | ----------------------------------------------------- 2 | ando | <ТЕКСТ> | учебник,дождь | личное,опыт |
Т.е. берутся данные из таблицы tm_posts по нику ando, ищется связка тегов и категорий по id поста в таблице tm_relationships. После чего получаем данные из таблицы tm_attributes. Эти данные сливаем в строку.
Вот что получилось сделать:
SELECT t1.*, GROUP_CONCAT(t3.attr_name) As `tags` FROM tm_posts t1 JOIN tm_relationships t2 ON t1.id = t2.id_post JOIN tm_attributes t3 ON t3.id = t2.id_attr WHERE t1.name= 'ando' AND t3.sign = 'tag' GROUP BY t1.id
Этот код выводит все, кроме категорий. Как мне сюда добавить еще и категории.
-----------------------------Добавлено:
Необходимо выбрать все записи из БД с категорией "личное", но при этом к каждой записи нужно приклеить колонку со связкой тегов.
Структура таблиц остается такая же. Результат должен выдать, примерно такой:
id | name | text | tags | category | ---------------------------------------------------------------------- 2 | ando | <ТЕКСТ> | учебник,дождь | личное | 5 | ник | <ТЕКСТ> | какие-то теги | личное | 6 | ник | <ТЕКСТ> | какие-то теги | личное |
Т.е. выбрались все записи с тегами, но только с определенной категорией "личное"


Ответ

Думаю можно сделать два join к tm_attributes наподобие
SELECT t1.*, GROUP_CONCAT(t3.attr_name) As `tags`,GROUP_CONCAT(t4.attr_name) As `cats` FROM tm_posts t1 JOIN tm_relationships t2 ON t1.id = t2.id_post left JOIN tm_attributes t3 ON t3.id = t2.id_attr and t3.sign = 'tag' left JOIN tm_attributes t4 ON t4.id = t2.id_attr and t4.sign = 'cat' WHERE t1.name= 'ando'
GROUP BY t1.id
Для выбора только категории личное пришел в голову только такой запрос fiddle
1) сначала выбираем все Post с категория личное
2) делаем join к категориям
select cat_data.*, GROUP_CONCAT(t3.attr_name) As `tags` from (select t1.*,t4.attr_name from tm_attributes t4 join tm_relationships t2 on id_attr=t4.id join tm_posts t1 on id_post=t1.id where t4.sign = 'cat' and t4.attr_name='личное' ) cat_data join tm_relationships t2 on id_post=cat_data.id left JOIN tm_attributes t3 ON t3.id = t2.id_attr and t3.sign = 'tag' group by cat_data.id

Что правильно тестировать в юнит-тестах?

Предположим есть несколько классов A, B и C. Мы тестируем A. Остальные классы - моки. У класса A есть метод, внутри которого он использует B и C, и выдает результат.
Нужно-ли тестировать то, что класс A взаимодействует с B и C, или написать один тест, в котором будет проверяться результат выполнения метода A?
Делать ли такой тест в следующем случае:
class A implements B.OnBarCallback { private B b;
public A(B b) { this.b = b; }
public void foo() { b.bar(this); }
@Override public void onBar() { // do something } }
// тест вызова B void testCallB() { B mockB = mock(B.class); A a = new A(mockB); a.foo(); verify(mockB).bar(any(OnBarCallback.class)); }
// тест callback void testACallback() { B mockB = mock(B.class); A a = new A(mockB); a.onBar(); // do verify something }
Правильно ли вручную дергать метод колбэка в тесте?


Ответ

Если пойти совсем по правилам, то юнит тест должен тестить минимальную единицу кода. У меня есть такое внутреннее правило - если мне вдруг понадобилось продебажить выполнение юнит теста, так как я не понимаю, как оно работает - значит, это не юнит тест, он тестирует слишком большой кусок кода.
Поэтому, если классы В и С достаточно большие и не тривиальные (к примеру, они читают файлы с диска, скачивают с интернета), то лучше их замокать и в классе A тестить с моками. А если методы B/C складывают два числа, то я не вижу особой причины их мокать.
Нужно-ли тестировать то, что класс A взаимодействует с B и C
Но никто не отменяет тестов взаимодействия классов вместе. Просто это называется уже интеграционные тесты. И они также нужны и полезны.
или написать один тест, в котором будет проверяться результат выполнения метода A?
А вот сколько тестов написать - это уже философский вопрос. Но одного обычно мало бывает.

Объединение подколлекций в одну коллекцию с помощью Linq

“Один пользователь - одна база данных” - правильно ли, и если нет, то почему?

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


Ответ

Подход вполне возможный и в некоторых случаях - логичный. Называется такая архитектура мультитенантной, используется в облачных технологиях чаще всего.
Явные плюсы:
Sql доступ конкретного клиента можно (я бы даже сказал нужно) дополнительно ограничивать sql учеткой. Независимость клиентов друг от друга. Независимость данных клиентов друг от друга.
Что не совсем ясно по вашему вопросу и надо будет учитывать:
Есть ли общая точка входа для сервисных операций? Она должна быть либо защищена от клиентов, либо клиенты от неё. Какая архитектура приложения - клиент-БД или клиент-сервер-БД? В первом случае отдельная база на клиента выглядит обязательной, во втором - в зависимости от нагрузки и требований клиентов. Есть ли (нужна ли) у клиентов возможность обновления на разные версии программы? Одна база на всех не даст вам такую возможность.
Можно найти ещё причин, надо смотреть по ситуации.

Подскажите как сверстать эту секцию

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


Ответ

Как вариант
* { padding: 0; margin: 0; box-sizing: border-box; } .b { max-width: 960px; margin: 15px auto; display: flex; justify-content: space-between; counter-reset: b-item; } .b-item { max-width: 220px; margin: 0 auto; padding: 25px; position: relative; text-align: center; display: flex; flex-direction: column; } .b-item:nth-of-type(even) { padding-top: 50px; } .b-item:nth-of-type(even) p { order: 1; } .b-item:before, .b-item:after { border: 1px solid #ccc; width: 24px; height: 24px; line-height: 24px; text-align: center; border-radius: 50%; display: block; margin: 10px auto; position: relative; z-index: 99; background: #fff; } .b-item:nth-of-type(odd):after, .b-item:nth-of-type(even):before { counter-increment: b-item; content: counter(b-item)" "; } .b-item .fa { font-size: 26px; color: #c00; } .b-item .fa:after { content: ''; border-bottom: 1px dashed #555; width: 100%; height: 1px; position: absolute; top: 50%; left: 0; } .b-item .fa:nth-of-type(1):after { left: 50%; } .b-item:nth-of-type(odd) .fa:after { transform: rotate(-16deg); } .b-item:nth-of-type(even) .fa:after { transform: rotate(16deg); } .b-item:last-of-type .fa:after { border: none; } @media screen and (max-width: 767px) { .b { flex-wrap: wrap; } .b-item:nth-of-type(even) { padding-top: 25px; } .b-item .fa:after { display: none; } .b-item:nth-of-type(odd):after { display: none; } .b-item:before { counter-increment: b-item; content: counter(b-item)" "; } }

text text text text text text

text text text text text text

text text text text text text

text text text text text text

text text text text text text

text text text text text text


Android анимация вращения

Есть RelativeLayout с несколькими view внутри. Как сделать анимацию вращения вокруг оси Y как на рисунке?


Ответ

Используйте класс ObjectAnimator. Очень прост в использовании
ObjectAnimator animation = ObjectAnimator.ofFloat(yourView, "rotationY", 0.0f, 360f); animation.setDuration(2400); animation.setRepeatCount(ObjectAnimator.INFINITE); animation.setInterpolator(new AccelerateDecelerateInterpolator()); animation.start();

Мусорные картинки при обновлении имеющейся

Думаю это большая проблема в Django, но панацеи (как я понимаю) нет.
У меня есть модель пользователя с полем ImageField для аватарки. Из личного кабинета пользователь меняет аватарку передавая через форму новую картинку. Все хорошо, аватарка изменена и храниться у меня в папке, но старая аватарка(фаил) так же остался в папке!
Есть ли универсальный способ чистить "устаревшие" картинки? Возможно требуется переопределение метода save() когда я сохраняю форму в view? Я не совсем понимаю как это все сделать...


Ответ

Да, такая особенность у django действительно имеется - старые картинки не удаляются.
Проблему можно решить несколькими методами
Переопределить метод save. Суть заключается в том, что нужно получить объект, хранящийся на сервере, проверить различаются ли между ними изображения и удалить старое:
def save(self, *args, **kwargs): try: this = MyModelName.objects.get(id=self.id) if this.MyImageFieldName != self.MyImageFieldName: this.MyImageFieldName.delete() except: pass super(MyModelName, self).save(*args, **kwargs) Отслеживать сигналы pre_save и post_save соответственно манипулируя удалением из них (сложно) Время от времени проходиться периодической задачей по файлам в папке и всем полям FileField, выискивая и удаляя лишние
Но как по мне лучше всего с этой задачей справляется дополнение django cleanup. Поэтому советую установить его и забыть про эту проблему