Страницы

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

понедельник, 23 декабря 2019 г.

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

#cpp #linux #qt #qt4


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


Ответы

Ответ 1



#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\n", _PROGRAM_NAME, (unsigned) uid); exit (EXIT_FAILURE); } enSO - How to get the username in C/C++ in Linux?

Какой формат scanf использовать для ввода bool

#c


Всем привет! 

scanf("%i", &reverse_sort);  


Компилятор ругается на несовместимость спецификатора и вводимых данных:


  /home/yura/gitclone/c_git/arr_sort.c|15|предупреждение: format «%i» expects argument
of type «int *», but argument 2 has type «_Bool *» [-Wformat=]|

    


Ответы

Ответ 1



Один из случаев, когда разные части стандарта подтягиваются с разной скоростью. Не существует пока спецификатора для bool-переменных. Корректный способ сделать то, что Вы хотите: int temp; bool reverse_sort; scanf("%i", &temp); reverse_sort = temp;

Ответ 2



Такого формата нет. Считывайте int - а потом уже приводите к bool.

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

#html #css #bootstrap #form #валидация


Доброго времени суток, форумчане! 

Подскажите пожалуйста, почему не работает валидация формы. Делаю всё, как тут:
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"} ) )
{
    
    
}


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



    


Ответы

Ответ 1



В коде инициализации валидатора ошибка - скобка поставлена неверно и поле 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 мне не известно,
перешерстил все и ничего не нашел.
    


Ответы

Ответ 1



Решая перебором, следует комбинировать оба подхода. Для 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; }

Ответ 2



Очевиден тот факт, что в случае нулевого остатка операция деления даёт сразу пару делителей числа p (делитель и частное), причём половина делителей лежит слева от числа q=[sqrt(p)], а половина - справа. При больших p неизбежно q << p, и части (q и p-q) явно неравны, поэтому, к примеру, при факторизации стараются начинать с меньших делителей. Заметим, что при исходных данных (s=3, p=94) нахождение требуемого искомого делителя "в лоб" потребует 91 операцию перебора, в то время как факторизация - всего лишь одну. Причина кроется в низкой эффективности поиска делителей на интервале (q,p), потому что их плотность там мала, а требуемый делитель 2 (который является ключом к частному 47) мы проскочили. Т.е. в случае s < q есть риск превратить поиск делителя в рулетку. Другое дело, если s>>q. Перебирая (в обратном порядке) частные от деления p на t, t-1,...,2, где t = [q/s], мы повышаем шансы найти требуемый делитель. Т.е. в этом случае параметр s может принести пользу. Но что же делать при s < q? В этом случае остаётся выбор - пойти на факторизацию или ограничиться проверкой делителей. Во втором случае можно начать с перебора делителей по возрастанию, начиная с s+1, но перебор на интервале [q,p/s) вести с помошью таблицы неиспользованных частных (в обратном порядке), а на интервале [p/s,p) -- непосредственно вычисляя оставшиеся частные делением p на s, s-1, ....

Ответ 3



Вначале надо факторизовать число, потом построить список его делителей, отсортировать его по возрастанию и найти, в какое место попадает s, и взять следующий справа делитель. Факторизовать чем-нибудь отсюда, дальше проще. А перебирать задолбаешься на первом же Р больше миллиона.

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

#javascript #коллекции #underscorejs


Каким образом эффективнее всего найти индекс объекта коллекции, который имеет указанное
свойство. Например, нужно найти индекс объекта коллекции, который имеет свойство id
равное 123.
Сейчас при помощи Underscore делаю так:

_.indexOf(collection, _.findWhere(collection, {id: 123}));


Подскажите, пожалуйста, более красивый и эффективный способ, если таковой имеется.
    


Ответы

Ответ 1



Как в 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)

Ответ 2



С точки зрения функциональности, все отлично. С точки зрения скорости, Lodash работает быстрее Underscore. Вот пара тестов: Underscore (у меня около 60 мс): http://jsfiddle.net/IonDen/amcfve44/ Lodash (у меня около 40 мс): http://jsfiddle.net/IonDen/L5pbdgqs/ Код теста: var collection = [{id: 321}, {id: 123}, {id: 333}]; // warm up for (var i = 0; i < 100000; i++) { var test = _.indexOf(collection, _.findWhere(collection, {id: 123})); } console.time('indexOF: ') for (var i = 0; i < 100000; i++) { var test = _.indexOf(collection, _.findWhere(collection, {id: 123})); } console.timeEnd('indexOF: ')

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

#php #phpstorm #openserver #xdebug


Делаю проверку и отладку с помощью xDebug.
OpenServer + xDebug + phpStorm.

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


Ответы

Ответ 1



ob_get_contents() — Возвращает содержимое буфера вывода Пример использования

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

#c_sharp #ооп


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


Ответы

Ответ 1



Полиморфизм подтипов -- это то, что обычно понимают под полиморфизмом в объектно-ориентированном программировании. Он заключается в том, что вызывающий код использует объект, опираясь только на его интерфейс (контракт), не зная при этом фактического типа. Такой подход позволяет подтипам реализовывать свое поведение и т.о. изменять поведение программы без перекомпиляции кода-клиента. Возьмем пример из Википедии: 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 -- мы получаем разное поведение (на консоль выводится разный текст).

Создание ZIP-архива программно

#java #android #zip


Здравствуйте! Уже несколько дней мучаюсь с проблемой:
Мне нужно программно создать архив, и поместить в него файлы из массива.
Использовал cледующий код:

private static final int BUFFER = 80000;

public void zip(String[] _files, String zipFileName) {
    try {
        BufferedInputStream origin = null;
        FileOutputStream dest = new FileOutputStream(zipFileName);
        ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
                dest));
        byte data[] = new byte[BUFFER];

        for (int i = 0; i < _files.length; i++) {
            Log.v("Compress", "Adding: " + _files[i]);
            FileInputStream fi = new FileInputStream(_files[i]);
            origin = new BufferedInputStream(fi, BUFFER);

            ZipEntry entry = new ZipEntry(_files[i].substring(_files[i].lastIndexOf("/")
+ 1));
            out.putNextEntry(entry);
            int count;

            while ((count = origin.read(data, 0, BUFFER)) != -1) {
                out.write(data, 0, count);
            }
            origin.close();
        }

        out.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}


Вроде все идет хорошо, архив на месте, но:
Сам архив должен весить порядка 15 МБ, а весит всего 10,56 МБ, и архиватор говорит:
"Архив поврежден". Возможно, конечно, вес сокращен из-за сжатия, но почему архиватор
отказывается открывать его, и как убрать сжатие? Подскажите, пожалуйста. Заранее спасибо!
    


Ответы

Ответ 1



Проблема у вас в том, что вы обрабатываете не все исключения и закрываете выходной поток не в секции finally, вот так примерно должен выглядеть рабочий код private static final int BUFFER = 80000; public void zip(String[] files, String zipFileName) { ZipOutputStream out = null; try { out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFileName))); byte data[] = new byte[BUFFER]; for (int i = 0; i < files.length; i++) { processFile(out, data, files[i]); } } catch (IOException e) { e.printStackTrace(); } finally { close(out); } } private void processFile(ZipOutputStream out, byte[] data, String file) { BufferedInputStream origin = null; try { origin = new BufferedInputStream(new FileInputStream(file), BUFFER); ZipEntry entry = new ZipEntry(file.substring(file.lastIndexOf("/") + 1)); out.putNextEntry(entry); int count; while ((count = origin.read(data, 0, BUFFER)) != -1) { out.write(data, 0, count); } } catch (IOException e) { e.printStackTrace(); } finally { close(origin); } } private void close(Closeable closeable){ if (null != closeable){ try { closeable.close(); } catch (IOException ignored) { } } }

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

#php #postgresql #pdo


В 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();

    


Ответы

Ответ 1



Вместо таких операторов можно использовать соответствующие функции (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.

Ответ 2



Для решения этой ситуации на http://stackoverflow.com предлагают создать свои собственные операторы без символа ? и выглядит это вот так: -- Because PHP::PDO replace symbol '?' into SQL-query we can not use this operator for work with JSONB type. -- alternative operator for '?' CREATE OPERATOR ~@ (LEFTARG = jsonb, RIGHTARG = text, PROCEDURE = jsonb_exists); -- alternative operator for '?|' CREATE OPERATOR ~@| (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_any); -- alternative operator for '?&' CREATE OPERATOR ~@& (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_all); Теперь мною приведенный выше PHP-код стал рабочим (разумеется я заменил оператор ?| на ~@| $statement = "SELECT id FROM public.parameter WHERE variations ~@| array[ '" . mb_strtolower( $title ) . "' ] LIMIT 1 OFFSET 0;"; $sth = $this->pdo->prepare( $statement ); $sth->execute(); Но, друзья, это ведь костыль!

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

#c_sharp #net #entity_framework


Пишу программу для учета поставщиков, и заказов у данных поставщиков с использованием
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 передаётся из другой формы.

В чем ошибка?
    


Ответы

Ответ 1



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

Ответ 2



А у Вас в структуре базы для таблицы Contractor первичный ключ создался как ContractorId? Возможно Вам поможет явное указание ключей для Entity Framevork, попробуйте так. Для поставщика: public class Contractor { [Key] public int ContractorId { get; set; } ... } Для заказа: public class Order { [Key] public int OrderId { get; set; } ... [ForeignKey("Contractor ")] public int ContractorId { get; set; } public virtual Contractor Contractor { get; set; } ... }

RecyclerView в CoordinatorLayout

#android


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


Ответы

Ответ 1



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

Ответ 2



Если я вас правильно понял, то вам нужно использовать Quick return pattern

Вызов функции из другого файла

#javascript #jquery


Есть общий файл (main.js) для всех скриптов, в нём прописана функция для кнопки "наверх":

function button_top_right (n) {
    var top_button = $("#main").offset().top;
    $("#top_right").hide();
    $(window).scroll(function () {
        if ($(this).scrollTop() > top_button + n) {
            $('#top_right').fadeIn().addClass("fixed");
        } else {
            $('#top_right').fadeOut();
        }
    });
};
button_top_right (1500);


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

$(document).ready(function () {
    button_top_right (100);
});


Скрипт не срабатывает с ошибкой:


  Uncaught ReferenceError: button_top_right is not defined


main.js подгружается раньше, чем вызов функции.
Что я делаю не так? 
    


Ответы

Ответ 1



Когда функция объявлена внутри document.ready, обратиться к ней извне не получится. Достаточно вынести саму функцию, а её вызовы оставить внутри document.ready: function button_top_right(n) { ... }; $(document).ready(function() { button_top_right(1500); }); Так как внутри функции button_top_right при каждом вызове функции добавляется обработчик события scroll для window, имеет смысл убирать предыдущий обработчик либо перед вызовом функции, либо внутри функции перед добавлением нового: $(window).off("scroll").on("scroll", function() { ... });

Как передать значение из активити в фрагмент

#android #android_fragment #activity


Есть активити которое вызывает фрагменты через интефейс. И нужно при создании екземпляра
фрагмента передать ему значение. Я использовал конструктор в Фрагменте, но Андроид
Студия говорит что так делать нельзя. Вообщем вопрос как передать из активити в Фрагмент
значение?
    


Ответы

Ответ 1



В активити экземпляру фрагмента через .setArguments передавать свой Bundle с параметрами Bundle bundle = new Bundle(); bundle.putInt(key, value); fragment.setArguments(bundle); А в самом фрагменте получить переданный Bundle Bundle bundle = this.getArguments(); if (bundle != null) { int i = bundle.getInt(key, defaulValue); } Источник: https://stackoverflow.com/questions/15392261/android-pass-dataextras-to-a-fragment

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

#python


Например следующий код не выдаст ошибки:

 rs = r'Cat\'s home'


А этот код выдаст:

rs = r'Cat\\'s home'


То же самое, так ошибки не будет:

 rs = r'Cat\\\'s home'


А этот код выдаст:

rs = r'Cat\\\\'s home'


И так далее...

Этот факт я запомнил, но почему так получается не понимаю
    


Ответы

Ответ 1



Ответ пользователя @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

Ответ 2



Потому, что обратный слеш - спец символ, который требуется экранировать вторым обратным слешем. Одинарная кавычка, в данном случае, также требует экранирование обратным слешем (поскольку она используется для выделения строки, если строку обрамите двойными кавычками, то в строке одинарная не требует экранирования и наоборот) Здесь вы обратным слешем экранируете одинарную кавычку rs = r'Cat\'s home' Здесь же появляется еще один обратный слеш, который требуется экранировать еще одним. rs = r'Cat\\'s home' Здесь же вы экранировали и второй слеш rs = r'Cat\\\'s home' А здесь добавили еще один слеш, который также требуется экранировать rs = r'Cat\\\\'s home'

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

#android #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)


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


Ответы

Ответ 1



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

Типы переменных в Ruby

#ruby


Чем в Ruby отличаются переменная экземпляра класса и переменная объекта?
    


Ответы

Ответ 1



Во первых, объект - это экземпляр класса. Это одно и то же понятие. Еще можно часто встретить слово "инстанс", тоже означающее "экземпляр класса". Во вторых, кроме инстанс-, и класс-переменных, есть ещё одна интересная вещь - класс-инстанс переменная (или инстанс-переменная уровня класса). Они похожи на классовые переменные. Но если классовые переменные расшаривают значение и для классов, унаследованных от текущего, то класс-инстанс переменные - только для конкретного класса, и не наследуются. (они являются предпочтительным решением, если нет нужды в расшаривании переменной с наследниками). Фишка в том, что в руби, любой объявленный класс является экземпляром класса Class. И у этих самых объектов класса Class тоже могут быть свои инстанс-методы (уровня класса). Ну и к слову: любой объект в руби (в том числе класс), является экземпляром класса Object. Отсюда выражение "класс - это объект, а объект - это класс".

Ответ 2



Каждый класс является инстансом типа Class и каждый класс является подклассом типа Object (в 1.8 - in 1.9 каждый класс является подклассом BasicObject'a). Таким образом, каждый класс является объектом в том смысле, что он является экземпляром подкласса Object, т.е. класса. Другими словами, нету отличий между перменной класса и объекта.

Ответ 3



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

Ответ 4



ничем не отличается, так как объект это экземпляр класса

Ответ 5



Свои 5 копеек.. ) Насколько я понял речь идет о экземпляре класса и объекте класса. Объект класса(читай класс) - это своего рода "каркас" по которому строятся экземпляры класса.. К примеру переменные объекта класса являются общими для всех экземпляров класса.. class SomeClass #SomeClass - это объект класса(собственно каркас) @@class_var = -10 # это переменная объекта класса(или просто класса) она имеет #одно значение для всех экземпляров класса и все могут изменить ее def initialize(x,y) @x,@y = x,y #это переменные экземпляра класса они у каждого экземпляра свои # и имееют свои значения для каждого экземпляра end end some_obj = SomeClass.new(-1,-1) #some_obj это экземпляр класса его @x, @y = -1,-1 а его @@class_var = -10 some_obj_next = SomeClass.new(-2,-2) #some_obj_next это экземпляр класса его @x, @y = -2,-2 а его @@class_var = -10(ибо это общая переменная объекта класcа для всех )

Как можно проанализировать качество Java проекта?

#java


Один мой коллега обратился ко мне с просьбой проанализировать написанный его группой
программистов проект. Проект писался в течении 4-х лет группой из 10 программистов,
с использованием технологии Spring. Можете ли вы поделиться некоторыми идеями, какие
инструменты, методы и классификаторы вы используете для анализа качества написания
проектов написанных на Java.
    


Ответы

Ответ 1



"Качество написания проекта", на мой взгляд, складывается из двух вещей: Низкоуровневой: непосредственно качество кода. Для такой проверки используйте статический анализатор кода, он найдет потенциально проблемные места (логические ошибки в условиях, опасные паттерны и т.д.). Существуют как отдельные тулы, так и встроенные в IDE (например, в IntelliJ Idea). Высокоуровневой: качество проектирование, адекватность архитектуры решения. Такое оценивается только анализом требований и готового решения, и требует немалого опыта. Но позволяет ответить на разные вопросы, например: Не загнется ли проект через полгода от незначительных изменений в требованиях? Сложно ли вносить изменения в существующий код? В какой-то степени это даже более важное качество, чем качество кода, поскольку исправлять ошибки этого уровня очень сложно и дорого.

Ответ 2



Воспользуйтесь статическим анализатором. Ссылку на их список вам дали в комментарии. Так же стоит провести профилирование и нагрузочное тестирование (на wiki так же есть списки инструментов).

Ответ 3



PMD стандард, в целом, для этих целей со всеми плюшками и в Eclipse и для Jenkins.

WPF DateTime Format

#c_sharp #net #wpf #xaml


Есть TextBox текстовое поле которого биндится к полю типа DateTime. 
Сейчас форматирование заданно следующим образом:

Text="{Binding Date, Mode=OneWay, StringFormat=\{0:D\},ConverterCulture=ru}"


Выводит он соответственно примерно следующее: 12 ноября 2015г

А нужно чтобы он выводил следующее: 12 ноября 2015г (четверг)

Как этого добиться?
    


Ответы

Ответ 1



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

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

#java #android #cpp #android_ndk


Подскажите, как передать изображение из библиотеки на 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
, но это недостаточно для решения.
    


Ответы

Ответ 1



Верните из 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); } Надеюсь, идея вам понятна. Если вопрос производительности для вас критичен, почитайте это.

Ответ 2



По моему опыту несмотря на одно копирование данных, самый быстрый способ (если C-функция работает с форматом raw). К сожалению я не нашёл способа совсем без копирования. Часть класса java: native ByteBuffer newBitmap(int width, int height, int bpp); native void freeBitmap(ByteBuffer buf); public static final Config[] colormode= new Config[]{null, Config.ALPHA_8, Config.RGB_565, null, Config.ARGB_8888}; public Bitmap getBitmap(int width, height, bytePerPixel) { Bitmap b=Bitmap.createBitmap(width, height, colormode[bytePerPixel]); // подготавливаем место под картинку ByteBuffer bbuf= newBitmap(width, height, bytePerPixel); // получаем данные из C if(bbuf!=null) { if(bbuf.remaining() > bitmap.getRowBytes()*bitmap.getHeight()) // если картинка оказалась длиннее bbuf.limit(bitmap.getRowBytes()*bitmap.getHeight()); bitmap.copyPixelsFromBuffer(bbuf); // копируем буфер в картинку freeBitmap(bbuf); // освобождаем буфер return bitmap; }else return null; } C++: #include #include extern "C" JNIEXPORT jobject JNICALL Java_org_myclass_newBitmap(JNIEnv * env, jobject _this, jint width, jint height, jint bpp) { unsigned char *pix = malloc(width*height*bpp); if(!pix) return 0; for(int i=0; i< width; i++) for(int j=0; j< height; i++) for(int k=0; k< bpp; k++) { // как-то заполняем pix[j*bpp*width+i*bpp+k]= k==3? 255 : i*k+j*(2-k); } return env->NewDirectByteBuffer(pix, width*height*bpp); } extern "C" JNIEXPORT void JNICALL Java_org_myclass_freeBitmap(JNIEnv * env, jobject _this, jobject bbuf) { free(env->GetDirectBufferAddress(bbuf)); } jint JNI_OnLoad(JavaVM* vm, void* reserved) { return JNI_VERSION_1_6; }

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

#java #android #android_studio #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")

    


Ответы

Ответ 1



Когда приходит результат покупки, то в поле 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

#cpp #qt #qtcreator


Я понимаю, как включить поддержку 11 стандарта С++ в каждом отдельном проекте Qt.
В .pro файле пишем:

CONFIG += C++11


и все работает.

Можно ли настроить Qt Creator, чтобы он автоматически добавлял эту строчку в файл
проекта? Т.е. каждый вновь создаваемый проект должен сразу создаваться с этой опцией.
Гугл как-то не очень помогает...
    


Ответы

Ответ 1



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

Дебагер в PHPStorm не подхватывает другие страницы

#phpstorm #xdebug


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


Ответы

Ответ 1



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

Как парсить данные из WebView

#javascript #android #html #парсер #webview


Делаю мобильное приложение для сайта. Сайт не мой, API нет, поэтому его приходится
парсить. Думал обойдусь только JSOUP, но встал вопрос о том, как обрабатывать javascript
кнопки. Позадавав вопросы на англоязычном стаке мне сообщили, что с помощью JSOUP мне
не обработать javascript. 
Решил делать через WebView, но теперь столкнулся с проблемой -  как спарсить страничку
которая сейчас отображена в webview?
    


Ответы

Ответ 1



РЕШЕНИЕ: Пишем обработчик WebView и втыкаем туда Handler. Этот Handler будет драть для нас html странички сразу по завершении загрузки. У меня получилось примерно так: String shit; @JavascriptInterface @SuppressLint("SetJavaScriptEnabled") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); webview = (WebView) findViewById(R.id.webView); webview.setWebViewClient(new MyWebViewClient()); webview.getSettings().setJavaScriptEnabled(true); webview.getSettings().setDomStorageEnabled(true); webview.getSettings().setSaveFormData(true); webview.getSettings().setSavePassword(true); webview.getSettings().setLoadsImagesAutomatically(false); webview.addJavascriptInterface(new MyJavaScriptInterface(), "HtmlHandler"); webview.setWebViewClient(new MyWebViewClient() { @Override public void onPageFinished(WebView view, String url) { webview.loadUrl("javascript:window.HtmlHandler.handleHtml" + "(''+document.getElementsByTagName('html')[0].innerHTML+'');"); } }); webview.getSettings().setUserAgentString("Chrome/41.0.2228.0 Safari/537.36"); webview.loadUrl("Ваш Сайт"); } Далее пишем класс MyJavaScriptInterface в котором мы распарсим выдернутую html страницу с помощью JSOUP: private class MyJavaScriptInterface { @JavascriptInterface public void handleHtml(String html) { Document doc = Jsoup.parse(html); shit = doc.select("span[id=j_id178]").first().text(); MainActivity.this.setTitle(shit); } } Естественно еще нужно подключить библиотеку JSOUP в файле build.gradle: dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.android.support:design:23.1.1' compile 'org.jsoup:jsoup:1.8.3' //вот наша библиотека } Все супер! Теперь заголовок моей Activity принял значение текста в этом id.

Плотная упаковка плавающих div по вертикали

#html #css #вёрстка #html5 #css3


Обычные плавающие div выстраиваются в строки с высотой самого высокого элемента. Вот так:


Google+ делает вёрстку на порядок компактней и красивей. Вот так:


Как можно добиться того, чтобы блоки подтягивались вверх, плотнее заполняя пространство?
Желательно - без динамического высчитывания границ каждого элемента и абсолютного позиционирования.
    


Ответы

Ответ 1



Стоит задумываться либо об одинаковости блоков по высоте, либо разбивать на несколько колонок и их уже заполнять блоками, а можно попробовать одни влево, другие вправо... Скорее всего на 2-м скрине сделано в три колонки.... Так же можно воспользоваться свойством марджин коллапс и задать нижние отступы блокам....(но это при небольших разбегах высоты...) Примерно вот накидал вариант со столбцами: #wrapper{ width:770px; outline:1px solid #9F00BF; } #cols1{ width:250px; float:left; margin:0; } #cols2{ width:250px; margin: 5px 260px; } #cols3{ width:250px; float:right; margin:0; } .a4{ width:245px; height:150px; background:#66f; margin:5px; } .a5{ width:245px; height:100px; background:#66f; margin:5px; } .a6{ width:245px; height:150px; background:#66f; margin:5px; } .a7{ width:245px; height:125px; background:#66f; margin:5px; }


Ответ 2



Не нашёл нигде CSS/HTML решения. Буду благодарен, если кто подскажет. Но есть вот такой вариант на jQuery: http://masonry.desandro.com/ Итоговый результат:

Ответ 3



Пусть блоки, множество блоков заключим в один див, с фиксированной шириной допустим 80%. Далее в стилях каждого из малых блоков внутри прописать display: block; height:100px width:30%; float:none Вот так. .Osnovnoiblock{width:80%;} .Malyiblock{display: block; height:100px width:30%; float:left; border:1px solid #000000;} .text{width:100px;}
Заголовок
Текст в блоке под заголовком
Заголовок
Текст в блоке под заголовком
Заголовок
Текст в блоке под заголовком
Заголовок
Текст в блоке под заголовком
Заголовок
Текст в блоке под заголовком
Заголовок
Текст в блоке под заголовком
Заголовок
Текст в блоке под заголовком
Заголовок
Текст в блоке под заголовком
Заголовок
Текст в блоке под заголовком
Заголовок
Текст в блоке под заголовком
Заголовок
Текст в блоке под заголовком
Заголовок
Текст в блоке под заголовком
Заголовок
Текст в блоке под заголовком
Заголовок
Текст в блоке под заголовком
Заголовок
Текст в блоке под заголовком
Заголовок
Текст в блоке под заголовком
Заголовок
Текст в блоке под заголовком
Css: .Osnovnoi block{width:80%;} .Malyi block{display: block; height:100px width:30%; float:none} Как поведет себя таблица?

Ответ 4



Вариант 1: .flexboxes { display: flex; flex-wrap: wrap; height:200px; flex-direction: column; } .flexboxes > div {width:200px;background-color:red;margin:3px;} .block0 {height: 60px;} .block1 {height: 80px;} .block2 {height: 70px;} .block3 {height: 90px;} .block4 {height: 80px;} .block5 {height: 100px;}
Вариант 2 (с использованием скриптов): $(function() { $('.flexboxes').masonry({ itemSelector: 'div' // обращаемся к пунктам }); }); .flexboxes { display: flex; flex-wrap: wrap; height:200px; width: 630px; } .flexboxes > div {width:200px;background-color:red;margin:3px;} .block0 {height: 60px;} .block1 {height: 80px;} .block2 {height: 70px;} .block3 {height: 90px;} .block4 {height: 80px;} .block5 {height: 100px;}


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

#sql #база_данных #полиморфизм


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

SELECT Авто.Марка, Авто.Модель, Наименование FROM Авто
INNER JOIN Авто.Внешний_ключ_владельца.Таблица ON Авто.Внешний_ключ_владельца.ID
= Авто.Владелец.ID


И возможный результат:
"Daewoo" "Nexia" "Иванов. И.И."
"Ford" "Focus" "ООО ТОРГОПТ"
"Schevrolet" "Camaro" "Сидоров С.В."
    


Ответы

Ответ 1



Структура данных должна быть такой, чтобы запросы по ней были максимально простыми. Если вам в вашем запросе нужно только Наименование от владельца, то в разделении людей и организаций нет никакого смысла. Это должна быть одна таблица Владельцы. Дополнительные поля могут быть как в той же таблице, так и в дочерних типа "данные юрлиц"/"данные физлиц". Все зависит от запросов, сравните ваш вариант: 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 для фио для организаций. Если вы планируете более сложную логику запросов (которую вы в вопросе не указали) то идите от нее. И идите путем простоты.

Ответ 2



Я бы предложил добавить в таблицу Автомобили поле "Тип Владельца", и в нем хранить лишь два варианта: "чел" и "орг". В зависимости от содержимого этого поля связывать поле Владелец либо с таблицей Людей, либо Организаций.

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

#sql #postgresql


есть таблица хранящая  вершины  в виде списков смежностей

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 

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


Ответы

Ответ 1



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 мы получаем именно изначального родителя.

Ответ 2



Как я понимаю вы рекурсию собираетесь от корня вести, попробуйте наоборот. От листьев к корню: SQL Fiddle PostgreSQL 9.3 Schema Setup: CREATE TABLE tree ("id" int, "parent_id" int) ; INSERT INTO tree ("id", "parent_id") VALUES (0, NULL), (1, 0), (2, 0), (3, 1), (4, 1) ; Query 1: WITH RECURSIVE go_up(id, parent_id) as ( select id, parent_id from tree union all select tree.id, tree.parent_id from go_up join tree on tree.id=go_up.parent_id ) select id, count(*) from go_up group by id order by id Results: | id | count | |----|-------| | 0 | 5 | | 1 | 3 | | 2 | 1 | | 3 | 1 | | 4 | 1 |

Удаление определенного количества байт с конца файла shell

#linux #shell


Необходимо средствами shell удалить с конца файла N-ое количество символов.

Использовал truncate -s $(( $(stat -c '%s' $file) - $n )) $file.

Проект переехал на BusyBox. truncate там нет. 
Есть идеи как еще это можно реализовать?
    


Ответы

Ответ 1



можно скопировать нужное количество байт (рассчитать ведь не сложно) от начала первого файла во второй с помощью программы dd: $ dd if=первый.файл of=второй.файл bs=1 count=количество можно пересобрать busybox с необходимой функциональностью: https://github.com/akretion/busybox-remastering/blob/master/coreutils/truncate.c

Ответ 2



Написать собственный truncate на C, откомпилировать, таскать с собой. Объясняю, почему C, а не питон или еще какая пакость - truncate - это один единственный системный вызов. Так что никакого рантайма за собой тащить не надо.

Как задать фон и цвет шрифта части текста в TextView на Андроид используя Html.TagHandler для неподдерживаемых HTML тэгов?

#java #android #android_textview


Дано:

Есть HTML код, в нём текст, в тексте код, заключённый в тэг Тут код. 

Задача:

Текст внутри тэга должен иметь нужный мне цвет и определённого цвета фон.

Вопрос: 

Как этого добиться, если учесть, что текст назначается (и должен продолжать назначаться)
TextView так:

textView.setText(Html.fromHtml(myAwesomeTextWithCode));

    


Ответы

Ответ 1



Для обработки неподдерживаемых тэгов надо передавать в качестве 3 аргумента метода Html.fromHtml экземпляр класса, расширяющего Html.TagHandler, в коем и будет происходить обработка всех неподдерживаемых на Android HTML тэгов: public class MyHtmlTagHandler implements TagHandler { @Override public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) { if (tag.equalsIgnoreCase("code")) { processCode(opening, output); } } private void processCode(boolean opening, Editable output) { int len = output.length(); if (opening) { output.setSpan(new ForegroundColorSpan(Color.RED), len, len, Spanned.SPAN_MARK_MARK); output.setSpan(new BackgroundColorSpan(Color.GREEN), len, len, Spanned.SPAN_MARK_MARK); } else { Object obj = getLast(output, BackgroundColorSpan.class); int where = output.getSpanStart(obj); output.removeSpan(obj); if (where != len) { output.setSpan(new ForegroundColorSpan(Color.RED), where, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); output.setSpan(new BackgroundColorSpan(Color.GREEN), where, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } } } private static Object getLast(Spanned text, Class kind) { /* * This knows that the last returned object from getSpans() * will be the most recently added. */ Object[] objs = text.getSpans(0, text.length(), kind); if (objs.length == 0) { return null; } return objs[objs.length - 1]; } } Т.е. теперь вы можете сделать так: String myAwesomeTextWithCode = "

некод-некод Тут код опять-не-код

"; textView.setText(Html.fromHtml(myAwesomeTextWithCode, null, new MyHtmlTagHandler()));

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

#стек #forth


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


Ответы

Ответ 1



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

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

#java #android #listview #checkbox


Создал listView с собственной разметкой, привязал к SimplApdapter
А в разметке есть checkbox,и мне нужно поставить на него слушатель.Я испробовал все,
не получается.Как решить данную проблему?

ListView listView = (ListView) findViewById(R.id.listView);
list = new ArrayList


Ответы

Ответ 1



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

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

#сеть #router


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

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


Ответы

Ответ 1



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

Ответ 2



если в маршрутизаторе установлен дистрибутив openwrt, то перезапуск всех сетевых подключений выполняется довольно стандартным для sysvinit способом: # /etc/init.d/network restart

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

#android #recyclerview


Есть список кликабельных CardView построенных с помощью RecyclerView и кастомного
Адаптера со стандартной реализацией. ViewHolder имплементирует OnClickListener. Отсутствует
анимация "касания" элемента. Т.е. при нажатии на любое cardView нет никакого отклика,
что нажатие действительно произошло, срабатывает только лишь один OnClickListener. 

Как можно прикрутить анимацию ripple эффекта? Вероятно есть уже готовые реализации
от самого гугла, но найти ничего не получается почему-то, кроме такого. 
Попробовал сделать, анимация действительно появилась, но теперь не работает метод
OnClickListener :) Вернее, работает, но только если нажимать на края cardview (видимо
там где у меня определен layout_margin и куда анимация нажатия не достает). Как можно
решить проблему? Спасибо

разметка cardview.xml





    


Ответы

Ответ 1



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

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

#c_sharp #aspnet #aspnet_mvc #многопоточность #инспекция_кода


Ситуация: имеется приложение 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 я рассматривать не могу
    


Ответы

Ответ 1



Основные проблемы Нет 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 случаем?)



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


Ответы

Ответ 1



Команда целиком состоит из трех байт: 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, т.к. операция не между регистром/памятью и значением, а между регистром и регистром/памятью.

Ответ 2



Сравнение содержимого регистра с числов равноценно вычитанию из регистра этого числа. Т.е. по сути SUB eax 0 и CMP eax 0 равноценны по результату. При совпаднеии числе в результате получается ноль и срабатывает переход JZ В данном случае я думаю, что программист реализовавывл сравнение вычитанием, а CMP поставил слишком "умный" дизассемблер.

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

#алгоритм #математика


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


Ответы

Ответ 1



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

Ответ 2



То, что корни общего уравнения пятой степени[en] и выше не выражаются при помощи рациональных функций и радикалов от коэффициентов, было доказано норвежским математиком Нильсом Абелем в 1826 году. взято из Википедии. Это я имел ввиду когда говорил что алгоритма нет. Это вовсе не значит что корни можно найти, например подбором, или графическим методом (если они есть).

Ответ 3



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

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

#android


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


Ответы

Ответ 1



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

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

#cpp #c #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.
    


Ответы

Ответ 1



Самый простой метод: 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; } }

Ответ 2



Больше чтобы не забыть, вариант ответа от ixSci на С: #include int next(atomic_int *n) { int oldN = atomic_load(&n); while (1) { int newN = oldN + oldN*oldN + oldN*oldN*oldN; if (atomic_compare_exchange_strong(n, &oldN, newN)) { return newN; } }; }

Меняю цвет заголовков и оглавления, но когда в Word нажимаю “обновить оглавление”, цвет сбрасывается

#delphi #delphi_7 #com #ms_word


У меня есть кнопка, при нажатии на которую создаются пара заголовков, а потом, на
их основе создается оглавление. Я меняю цвет заголовков, и меняю цвет оглавления, но
потом, когда в файле Word нажимаю "обновить оглавление", установленный цвет оглавления
сбрасывается. Как сделать так, чтобы цвет оглавления не сбрасывался, а оставался?

procedure TForm1.Button1Click(Sender: TObject);
var
  wrd:OleVariant;
  StartRange, tableOfContentsRange: Variant;
  tableOfContents: Variant;
begin
  wrd:=CoWordApplication.Create;
  wrd.Visible:=true;
  wrd.documents.add(EmptyParam,EmptyParam, EmptyParam,EmptyParam);
  wrd.Selection.Style := 'Заголовок 1';
  wrd.Selection.Font.Color := RGB(255,0,0);
  wrd.Selection.Text:='Первый Заголовок';
  wrd.Selection.MoveDown;
  wrd.Selection.TypeParagraph;
  wrd.Selection.Style := 'Заголовок 1';
  wrd.Selection.Font.Color := RGB(255,0,0);
  wrd.Selection.Text:='Второй заголовок';
  wrd.Selection.MoveDown;
  wrd.Selection.TypeParagraph;

  StartRange := wrd.ActiveDocument.Range(0, 0);
  StartRange.Font.Color:=RGB(0,255,0);
  tableOfContents := wrd.ActiveDocument.TablesOfContents.Add(StartRange);
  tableOfContentsRange := tableOfContents.Range;
  tableOfContentsRange.Collapse;
  tableOfContentsRange.Select;
  wrd.Selection.TypeText('Оглавление' + #13);
  tableOfContents.Update;
end;

    


Ответы

Ответ 1



Все изменения, которые представлены в Вашем коде, применяются непосредственно к тексту. В вашем случае нужно изменять данные непосредственно у стилей, которым предстоит отображать оглавление (поскольку обновление оглавления практически "создает" его заново). Обратите внимание, что стили оглавления и стили основного текста - это разные вещи (хоть и могут ссылаться друг на друга), поэтому изменение одного скорее всего ни коим образом не повлияет на другое. Ниже - переделанный метод с достаточно подробными комментариями: procedure TForm8.btn1Click(Sender: TObject); var wrd, Document: OleVariant; Selection: Variant; tableOfContents: Variant; TOC1Style: OleVariant; begin // общий принцип - при работе с Word и другими приложениями из MS Office, // если какой-либо объект используется более 1 раза, то лучше // завести для него отдельную переменную и работать уже с ней. // иначе конструкции типа // wrd.ActiveDocument.ActiveWindow.Selection.блабла1 // wrd.ActiveDocument.ActiveWindow.Selection.блабла2 // будут приводить к тому, что КАЖДЫЙ раз сперва будет вызываться wrd на предмет получения ActiveDocument, // потом ActiveDocument чтобы получить ActiveWindow ... ну и так далее. // Всё это, получаемое многократно, может замедлить и без того не быструю работу с MS Office. // Помимо прочего это в некоторой степени ограждает от действий пользователя // к примеру, пока работает ваша программа, пользователь может клацнуть по другому документу // соответственно wrd.ActiveDocument будет уже указывать не на нужный нам документ. wrd := CoWordApplication.Create; wrd.Visible := true; Document := wrd.documents.add; Selection := Document.ActiveWindow.Selection; Selection.Style := wdStyleHeading1; // для установки стилей лучше использовать // вот такие встроенные константы. Иначе есть риск напороться на иноязычный // Office, в котором "верхний" стиль будет называться к примеру 'Header 1' Selection.Font.Color := wdColorRed; Selection.Text := 'Первый Заголовок'; Selection.MoveDown; Selection.TypeParagraph; Selection.Style := wdStyleHeading1; Selection.Font.Color := wdColorRed; Selection.Text := 'Второй заголовок'; Selection.MoveDown; Selection.TypeParagraph; // меняем стиль "Оглавление 1". В этом случае также лучше пользоваться константами. TOC1Style := Document.Styles.Item(wdStyleTOC1); TOC1Style.AutomaticallyUpdate := true; TOC1Style.Font.Color := wdColorGreen; // хочу зелененькое :) TOC1Style.Font.Italic := true; TOC1Style.Font.Bold := true; // создаем содержание tableOfContents := Document.TablesOfContents.add( Range := Document.Range(0, 0), RightAlignPageNumbers := true, UseHeadingStyles := true, UpperHeadingLevel := 1, // применяя стили заголовков от 1 (изменен нами) LowerHeadingLevel := 3, // до 3 IncludePageNumbers := true, AddedStyles := '', UseHyperlinks := true, HidePageNumbersInWeb := true, UseOutlineLevels := true); Document.Range(0, 0).Select; Selection.TypeText('Оглавление' + #13#10); Selection.Move(wdStory, 1); tableOfContents.Update; // это излишне, содержание после создания // обновляется автоматически. Вот если бы мы после его создания // изменили основное содержимое, тогда да, обновить содержание не помешает. end;