Страницы

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

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

Вызывать JS функцию и записать в переменную

#javascript #java #android


Возможно ли вызывать функцию, которая находится в html файле, который загружен в
WebView и записать результат выполнения этой функции в java переменную?
    


Ответы

Ответ 1



Попробуйте так: Напишите такой кастомный клиент: final class MyWebChromeClient extends WebChromeClient { @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) { Log.d("LogTag", message); result.confirm(); return true; } } Прикрепите его к своему WebView: mWebView.setWebViewClient(new HelloWebViewClient()); Теперь грузите скрипт в WebView: webView.loadUrl("javascript:alert(functionThatReturnsSomething)"); Получите результат в onJsAlert message. На практике не пробовал, но выглядит убедительно. Отпишитесь, получится ли.

Метод Рунге-Кутты 4 порядка на java

#java #методы #численные_методы


Я только начала изучать java, и многие элементарные вещи для меня являются непонятными.

Прощу вас подсказать мне, как решать систему взаимозависимых уравнений методом Рунге-Кутты!

Полное задание:

Для решения полученной задачи Коши для системы первого порядка вида:

y'= f(t,y), y(0)=y0

использовать метод Рунге_Кутты 4-го порядка точности:

k1 = f(tn , yn)
 k2 = f(tn + h/2 , yn + hk1 / 2)
 k3 = f(tn + h/2 , yn + hk2 / 2)
 k4 = f(tn + h , yn + h*k3)

yn+1=yn+h*(k1 + 2*k2 + 2*k3 + k4) / 6    

На отрезке [0,5] с точным решением 

y1=cos(x)/(1+e2x)1/2,

y2=sin(x)/(1+e2x)1/2.

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

y1' = –y2 + y1(y12 + y22 – 1),

y2' = y1 + y2(y12 + y22 – 1),

На отрезке [0,5] с точным решением 

y1=cos(x)/(1+e2x)1/2,

y2=sin(x)/(1+e2x)1/2.

Я пытаюсь реализовать только метод!
Сложность заключается в том, что производные у1 и у2 зависят друг от друга.
И правильно ли  я сделала, что производную в точке вычисляю по у1 и у2

public static double y1=Math.cos(x)/Math.pow(1 + Math.pow(Math.E, 2 * x),0.5);
public static double y2=Math.sin(x)/Math.pow(1+Math.pow(Math.E,2*x),0.5);

//   dy1/dx
public static double derviY1(double x,double y10,double y20){

    return -y20+y10*(Math.pow(y10,2)+Math.pow(y20,2)-1);
}

//   dy2/dx
public static  double derviY2(double x ,double y1,double y2){
    return y1 + y2*(Math.pow(y1,2) + Math.pow(y2,2) - 1);
}


И почему-то вычисляя y20[i+1] и y10[i+1] они у меня остаются неизменными, хотя я
в программе изменяю данные, которые в них входят.

for (int i = 0; i < n - 1; i++) {
    x = i * h;

    k1 = h * derviY1(x, y10[i], y20[i]);
    m1 = h * derviY2(x, y10[i], y20[i]);

    k2 = h * derviY1(x + h / 2, y10[i] + k1 / 2, y20[i] + k1 / 2);
    m2 = h * derviY2(x + h / 2, y10[i] + m1 / 2, y20[i] + m1 / 2);

    k3 = h * derviY1(x + h / 2, y10[i] + k2 / 2, y20[i] + k2 / 2);
    m3 = h * derviY2(x + h / 2, y10[i] + m2 / 2, y20[i] + m2 / 2);

    k4 = h * derviY1(x + h, y10[i] + k3, y20[i] + k3);
    m4 = h * derviY2(x + h, y10[i] + m3, y20[i] + m3);

    y10[i + 1] = y10[i] + h * (k1 + 2 * k2 + 2 * k3 + k4) / 6;
    y20[i + 1] = y20[i] + h * (m1 + 2 * m2 + 2 * m3 + m4) / 6;

    System.out.println("| " + x + " |" + " " + y10[i] + " " + "|" + " " + y20[i]
+ " " + "|");


Полный код программы:

import java.*;
import java.lang.Math.*;
import static java.lang.System.out;

public class Test {

    static double x;
    //start
    private static int a = 0;
    // stop
    private static int b = 5;

    public static double y1 = Math.cos(x) / Math.pow(1 + Math.pow(Math.E, 2 * x), 0.5);
    public static double y2 = Math.sin(x) / Math.pow(1 + Math.pow(Math.E, 2 * x), 0.5);

    //   dy1/dx
    public static double derviY1(double x, double y10, double y20) {

        return -y20 + y10 * (Math.pow(y10, 2) + Math.pow(y20, 2) - 1);
    }

    //   dy2/dx
    public static double derviY2(double x, double y1, double y2) {
        return y1 + y2 * (Math.pow(y1, 2) + Math.pow(y2, 2) - 1);
    }


    public static void main(String[] args) {
        int n = 10;
        double h = (b - a) / n;
        double k1, k2, k3, k4, m1, m2, m3, m4;
        double[] y10 = new double[n]; //array of values y1
        double[] y20 = new double[n]; //array of values y2
        y10[0] = 1 / Math.sqrt(2);
        y20[0] = 0;

        // Computation by 4th order Runge-Kutta
        //update x
        for (int i = 0; i < n - 1; i++) {
            x = i * h;

            k1 = h * derviY1(x, y10[i], y20[i]);
            m1 = h * derviY2(x, y10[i], y20[i]);

            k2 = h * derviY1(x + h / 2, y10[i] + k1 / 2, y20[i] + k1 / 2);
            m2 = h * derviY2(x + h / 2, y10[i] + m1 / 2, y20[i] + m1 / 2);

            k3 = h * derviY1(x + h / 2, y10[i] + k2 / 2, y20[i] + k2 / 2);
            m3 = h * derviY2(x + h / 2, y10[i] + m2 / 2, y20[i] + m2 / 2);

            k4 = h * derviY1(x + h, y10[i] + k3, y20[i] + k3);
            m4 = h * derviY2(x + h, y10[i] + m3, y20[i] + m3);

            y10[i + 1] = y10[i] + h * (k1 + 2 * k2 + 2 * k3 + k4) / 6;
            y20[i + 1] = y20[i] + h * (m1 + 2 * m2 + 2 * m3 + m4) / 6;

            System.out.println("| " + x + " |" + " " + y10[i] + " " + "|" + " " +
y20[i] + " " + "|");
        }
    }
}

    


Ответы

Ответ 1



У вас h = 0. Почему? Ведь вы ясно написали, что h = (5-0)/10. А проблема вот в чём. Ваше выражение (5-0)/10 сначала преобразуется в int, а потом уже в double. То есть происходит всё как-то так (int)((5-0)/10). После этой операции мантисса отбрасывается и получается полноценный 0. Достаточно привести к double одну из переменных, как всё выражение будет обработано, как для переменных с плавающей точкой. К примеру так: double h = ((double)b - a) / n; В этих преобразованиях есть более интересные моменты, о которых хотелось бы рассказать, то это уже другая история.

Выборка строк с последней датой

#mysql


Есть 3 таблицы:

1) Главная id, name

2) Таблица с датой, где pid = id в главной таблице.

id, pid, date, value


3) Таблица с датой в формате int, где pid = id в главной таблице. (yy-год, mm-месяц)

id, pid, yy, mm, value


В один запрос нужно посчитать кол-во строк, с записями из этих таблиц для последних
дат. Пробую два подхода:

SELECT
    COUNT(*)
FROM
    mainTable c
    LEFT JOIN subTable1 s1 ON c.id = s1.pid AND s.date IN (SELECT MAX(date) FROM
subTable1 WHERE pid = c.id) 
    LEFT JOIN subTable2 s2 ON c.id = s2.pid AND ((s2.yy*100) + s2.mm) IN (SELECT
MAX(yy)*10 + MAX(mm) FROM subTable2 WHERE pid=c.id)


Способ понятный, компактный, но очень долгий, на 40000 строк делается 60 секунд.

SELECT
    COUNT(*)
FROM (
    SELECT
        c.id AS id,
        MAX(s1.date) AS date1,
        MAX(s2.yy*100 + s2.mm) AS date2
    FROM
        mainTable c
        LEFT JOIN subTable1 s1 ON c.id = s1.pid
        LEFT JOIN subTable2 s2 ON c.id = s2.pid
    GROUP BY c.id
    ) tt
    LEFT JOIN LEFT JOIN subTable1 s1 ON tt.id = s1.cid AND s1.date IN (tt.date1)
    LEFT JOIN subTable2 s2 ON tt.id = s2.cid AND s2.yy*100 + s2.mm IN (tt.date2)


Способ не очень удобный, т.к. запрос получается гораздо длиннее, но зато на 40000
строк выполняется в 4 раза быстрее.

Подскажите, пожалуйста, почему такая разница? Можно ли как-то подправить 1й запрос,
чтобы устранить её? Может есть какой-нибудь иной способ, чтобы получить нужную мне
информацию?

P.S. На самом деле таблиц гораздо больше, запросы всё время дополняются, всё постарался
упростить, чтобы облегчить понимание задачи.

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


Ответы

Ответ 1



Допустим, с индексами вы разобрались. Теперь пойдем от SQL. Первый запрос выполняется долго, потому как вы берёте все записи из таблицы mainTable, а потом джойните отфильтрованные данные из двух других таблиц. Во втором случае вы сначала делаете фильтр, а потом выбираете данные, соответствующие этому фильтру. Полагаю, разница в скорости связана с этим. Смотрим на код. У вас Left Join, а значит выбираются все записи из mainTable (даже те, которым нет соответствия в таблицах subTable1 и subTable2). С этими данными связываются данные из двух других таблиц, при этом записи из mainTable может потенциально соответствовать по несколько записей в таблице subTable1 и subTable2. (Допускаю, что возможны связи один-к-одному, но исходя из приведенного SQL этого не видно.) А это значит, что выборке данные из mainTable могут быть посчитаны несколько раз (см. упрощенный пример, где данные умножены). Важно, кстати, отметить еще один момент: возможна ситуации, когда запись с некоторым pid есть в таблице subTable1, но нет записи с этим же pid в таблице subTable2. А значит, не ясно, что именно считать: все записи в таблице mainTable, которым есть соответствия в обеих зависимых таблицах (за определенный период), или же те, которым есть соответствие хотя бы в одной из таблиц? Интресный момент. Если выбрать только уникальные записи (небольшая модификация первого запроса из вопроса), то вы получите количество записей в таблице mainTable: SELECT COUNT(DISTINT c.id) FROM mainTable c LEFT JOIN subTable1 s1 ON c.id = s1.pid AND s.date IN (SELECT MAX(date) FROM subTable1 WHERE pid = c.id) LEFT JOIN subTable2 s2 ON c.id = s2.pid AND ((s2.yy*100) + s2.mm) IN (SELECT MAX(yy)*10 + MAX(mm) FROM subTable2 WHERE pid = c.id) эквивалентно: SELECT count(*) FROM mainTable В subTable1 пишется нормальная дата, в subTable2 пишутся год и месяц. Соответственно, фильтр по дате в subTable1 позволяет нам отфильтровать данные сильнее, чем фильтр по дате в subTable2. При этом возможны два сценария: данные пишутся в таблицы subTable1 и subTable2 одновременно (допустим, там хранятся бинарные данные или большие тексты), данные пишутся сначала в одну таблицу, потом - в другую и разница во времени может составлять минуты, часы или дни. Первый сценарий сильно облегчает запросы на выборку (достаточно одного фильтра). Второй создает проблемы, которые требуется учесть. Например, запись в subTable1 сделана 31 декабря 2015 года, а соответствующая запись в subTable2 - 1 января 2016. Приведенные в вопросе SQL-запросы такие пары проигнорируют если в таблице subTable1 появилась запись за 1 января. Пробуем построить запрос Если связь между главной и зависимыми таблицами "один-к-одному" (как обязательная, так и обязательная на одном конце), то таблица mainTable в запросе не нужна. Во вложенном запросе выбираем максимальные даты, джойним по этим датам данные из таблицы subTable1. По ID из главной таблицы выбираем данные из subTable2. Фильтруем по максимальной дате данные из subTable2: SELECT count(*) FROM (SELECT MAX(s1.date) max_date1, MAX(s2.yy)*100 + MAX(s2.mm) max_date2 FROM subTable1 s1 JOIN subTable2 s2) h LEFT JOIN subTable1 s1 ON s1.date = h.max_date1 LEFT JOIN subTable2 s2 ON s1.pid = s2.pid WHERE (s2.yy*100) + s2.mm = h.max_date2; Если данные в таблицы subTable1 и subTable2 пишутся в один и тот же день, то запрос можно упростить: SELECT count(*) FROM (SELECT MAX(s1.date) max_date1 FROM subTable1 s1) h LEFT JOIN subTable1 s1 ON s1.date = h.max_date1 LEFT JOIN subTable2 s2 ON s1.pid = s2.pid; Важно учесть, что запрос не считает записи из mainTable, которым ничего не соответствует в таблицах subTable1 и subTable2 (если связь "один-к-одному" обязательная на одном конце). Я бы рекомендовал такие записи считать отдельно, а потом суммировать результаты. Тип связи "многие-ко-многим" между главной и зависимыми таблицами вызывает вопросы, ключевые из которых: что именно нужно посчитать (см. второй абзац в самом начале) и какая логика заложена в БД (см. третий абзац)?

Ответ 2



Если я правильно понял у Вас есть main: id, name date: id, main_id, date, value strange_date: id, main_id, mm, yy, value и Вам надо найти количество записей с максимальной датой в date и strange_date в разрезе main_id? Я бы пошёл от противного: select main_id, cnt from ( select main_id, date, count(*) as cnt from ( select main_id, date from date union select main_id, str_to_date(concat(yy,'-',mm,'-01')) as date from strange_date ) group by main_id, date ) as a group by main_id, cnt having date = ( select max(date) from ( select main_id, date from date union select main_id, str_to_date(concat(yy,'-',mm,'-01')) as date from strange_date ) as b where b.main_id = a.id ) И сделал бы наверное ещё вьюхи на юнион для того чтобы запрос был красивый типа - all_date_records - чтобы не тащить разную логику работы с представлением даты.

Воспроизведение музыки в C#

#c_sharp #wpf #аудио


Как в WPF приложении из кода воспроизвести музыкальный трек mp3, если известен путь
к нему?
    


Ответы

Ответ 1



Можно использовать класс SoundPlayer - в WinForms. Или функцию PlaySound. Или WMPLib.WindowsMediaPlayer А в WPF приложениях - класс MediaPlayer. var player = new MediaPlayer(); player.MediaFailed += (s, e) => MessageBox.Show("Error"); player.Open(new Uri("../../Sound.mp3", UriKind.RelativeOrAbsolute)); player.Play();

Контракт Share в UWP

#c_sharp #xaml #uwp


Как реализовать кнопку "Поделиться" в UWP проекте?
    


Ответы

Ответ 1



Курите статью Add Sharing to your UWP App. По минимуму: Добавить кнопку: Добавить в обработчик нажатия вызов ShowShareUI: private void AppBarButton_Click(object sender, RoutedEventArgs e) { Windows.ApplicationModel.DataTransfer.DataTransferManager.ShowShareUI(); } Добавить обработку запроса на расшариваемые данные: Windows.ApplicationModel.DataTransfer.DataTransferManager.GetForCurrentView() .DataRequested += MainPage_DataRequested; void MainPage_DataRequested(Windows.ApplicationModel.DataTransfer.DataTransferManager sender, Windows.ApplicationModel.DataTransfer.DataRequestedEventArgs args) { if(!string.IsNullOrEmpty(ContentText.Text)) { args.Request.Data.SetText(ContentText.Text); args.Request.Data.Properties.Title = Windows.ApplicationModel.Package.Current.DisplayName; } else { args.Request.FailWithDisplayText("Nothing to share"); } }

Что такое <devdoc>?

#c_sharp #net


Копался в исходниках .NET Framework и обнаружил непонятные мне комментарии. Что это
за теги  что они дают и как ими пользоваться?


/// 
/// 
/// Provides 
/// methods and properties
/// to manage an application, such as methods to run and quit an application,
/// to process Windows messages, and properties to get information about an application. This
/// class cannot be inherited.
/// 


    


Ответы

Ответ 1



Как можно догадаться devdoc означает developer documentation, т.е. комменты для девелоперов. Тут в пункте 2.4.2 чуть более подробно.

Вывод в div через jquery.ajax постепенно, по мере загрузки

#jquery #ajax


Задача - при jquery.ajax-запросе выводить результат в div не тогда, когда он полностью
получен браузером, а по мере его загрузки. Нужно, если данные достаточно объёмные.
Событие success или complete не подходят, т.к. срабатывают уже после полной загрузки
данных.

Собственно, вопрос в том, есть ли вариант реализации? Деление данных на сервере на
части и пулинг - не рассматриваются.

Благодаря ответам (всем спасибо!) разобрался. Решение есть, основано на использовании
объекта jqXHR. Детали - по ссылке http://incode.pro/jquery/ajax-na-praktike-progress-bar-indikator-protsessa-zagruzki.html.
Прогресс-бар меня не интересовал, т.к. было невозможно рассчитать % загрузки, а вот
вывод данных возможен, если использовать свойство target.response объекта, возвращаемого
установленным обработчиком подгрузки. По ходу загрузки нужно лишь выводить в нужный
DOM-элемент тело ответа, которое имеется в target.response, причём целиком, не частями!.
Типа так:

$('#ResultBox').html(evt.target.response)
    


Ответы

Ответ 1



С частью html - всё достаточно просто, хотя и не так безоблачно. Для прогрессбара используют или тег (реже ), или создают кастомный из любого понравившегося html-элемента. Первые два не очень кроссбраузерны, но предусмотренный в них альтернативный текст, который можно использовать для показа процентов выполнения загрузки, немного исправляет положение. Со вторым вариантом - приходится повозится в CSS, но это не проблема для людей знающих. Мы остановимся на первом, т.к. у нас сейчас основная цель - разобраться с механизмом на JavaScript. Итак, создадим простую форму для загрузки файла и после поля файла, разместим прогресс-бар, в котором нас интересуют два атрибута: value - текущее значение и max - максимальное значение. Так как мы будем использовать проценты, значения будут колебатся от нуля до ста. Соответственно стартовое значение (value) должно быть "0", а максимальное (max) - "100":

В JS пишем код $.ajax запроса и добавляем к параметрам xhr, в callback-функции которого, мы можем работать с объектом XMLHttpRequest, изменяя или дополняя его поведение, получать доступ его свойствам и методам, устанавливать свои обработчики событий и т.д.: $(function(){ var progressBar = $('#progressbar'); $('#my_form').on('submit', function(e){ e.preventDefault(); var $this = $(this), formData = new FormData($this.get(0)); $.ajax({ url: $this.attr('action'), type: $this.attr('method'), contentType: false, processData: false, data: formData, dataType: 'json', xhr: function(){ // получаем объект XMLHttpRequest var xhr = $.ajaxSettings.xhr(); // добавляем обработчик события progress (onprogress) xhr.upload.addEventListener('progress', function(evt){ // если известно количество байт if(evt.lengthComputable) { // высчитываем процент загруженного var percentComplete = Math.ceil(evt.loaded / evt.total * 100); // устанавливаем значение в атрибут value тега // и это же значение альтернативным текстом для браузеров, не поддерживающих progressBar.val(percentComplete).text('Загружено ' + percentComplete + '%'); } }, false); return xhr; }, success: function(json){ if(json){ $this.after(json); } } }); }); }); Что касается серверной части, то там работаем с файлом/файлами, как если бы вы их загружали обычным способом. Готово! Теперь, чтобы протестировать на локальной машине, нужно выбрать файл побольше, иначе загрузка будет происходить практически моментально и работу прогрессбара, вы попросту не заметите. Что будет в обработчике в этом случае - не важно, главное, чтоб он был. И не забудьте перед тестированием, установить значение директивы upload_max_filesize чуть больше, чем загружаемый файл. Для временого изменения - это проще всего сделать в файле .htaccess, прописав строку: php_value upload_max_filesize 1000M # вместо 1000 - своё значение Источник: http://incode.pro/jquery/ajax-na-praktike-progress-bar-indikator-protsessa-zagruzki.html