Страницы

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

понедельник, 24 февраля 2020 г.

Можно ли запустить Genymotion и Android Studio на разных машинах?

#android #genymotion


В целях быстродействия, хотелось бы запустить эмулятор и студию на разных машинах,
возможно ли это ?
    


Ответы

Ответ 1



Да возможно. Genymotion все равно работает в виртуальной машине Oracle VM так что ему без разницы, а отладчику надо указать куда коннектиться. Со стороны студии придется врукопашную запускать ADB с указанием IP адреса где запущен GenyMotion: adb tcpip 5555 //говорим adb чтобы перешел в режим TCP/IP на порту 5555 adb connect 192.168.X.Y //коннектимся к хосту где запущен эмулятор По идее должно сработать.

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

#java #android


Дали тестовое задание : разработать андроид-приложение, которое будет подключаться
к новостному ресурсу (ria.ru) и закачивать в кэш оттуда данные.
Я относительный новичок в программировании и знаком только с Java SE.
Пытался гуглить по направлению веб сервисов для андроид но ничего не смог найти.

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

Спасибо!
    


Ответы

Ответ 1



URL url = new URL("http://ria.ru"); BufferedReader br = new BufferedReader(new InputStreamReader(url.openConnection().getInputStream())); String tmp; StringBuilder sb = new StringBuilder(); while((tmp = br.readLine()) != null) sb.append(tmp); String html = sb.toString(); Потом можно с помощью regex вытащить данные из html.

Ответ 2



Парсить страницы. Для изображений рекомендую picasso.

Авторизация пользователя vk с помощью cURL (PHP)

#php #вконтакте #curl #авторизация


Добрый день.

Необходимо авторизировать пользователя vk с помощью PHP скрипта и библиотеки cURL. 
Были рассмотрены следующие решения:


https://forum.antichat.ru/threads/426901/
http://sauron.org.ua/post/938


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

Получение значений lg_h и ip_h (работает, получает):

$url = 'http://vk.com';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT
6.1)");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
        'content-type: application/x-www-form-urlencoded',
        'origin: http://vk.com',
        'referer: http://vk.com/',
));
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

$content = curl_exec($ch);

preg_match_all("/name=\"ip_h\" value=\"(.*?)\" \\//s", $content, $ip_h);
preg_match_all("/name=\"lg_h\" value=\"(.*?)\" \\//s", $content, $lg_h);


Отправка запроса авторизации вида:

http://login.vk.com/?
act=login&
role=al_frame&
_origin=http://vk.com&
ip_h=$ip_h&
lg_h=$lg_h&
email=&
pass=


Сам скрипт:

$url = 'http://login.vk.com/?act=login';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:42.0)
Gecko/20100101 Firefox/42.0");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_POST, true);

$data = array(
    'act' => 'login',
    'role' => 'al_frame',
    '_origin' => 'http://vk.com',
    'ip_h' => $ip_h[0][1][0],
    'lg_h' => $lg_h[0][1][0],
    'email' => '',
    'pass' => ''
);

curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'content-type: application/x-www-form-urlencoded',
    'origin: http://vk.com',
    'referer: http://vk.com/',
));

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

curl_setopt($ch, CURLOPT_COOKIEJAR, '/home//Development/vk/cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, '/home//Development/vk/cookie.txt');

echo curl_exec($ch);


На выходе получаю следующее содержимое страницы:




В свою очередь куки принимают следующие значения:

Set-Cookie: remixmid=DELETED; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/; domain=.vk.com
Set-Cookie: remixsid=DELETED; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/; domain=.vk.com
Set-Cookie: remixsid6=DELETED; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/; domain=.vk.com
Set-Cookie: remixgid=DELETED; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/; domain=.vk.com
Set-Cookie: remixemail=DELETED; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/; domain=.vk.com
Set-Cookie: remixpass=DELETED; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/; domain=.vk.com
Set-Cookie: remixapi_sid=DELETED; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/;
domain=.vk.com
Set-Cookie: remixpermit=DELETED; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/; domain=.vk.com
Set-Cookie: remixsslsid=DELETED; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/; domain=.vk.com


Смею предположить, что не удается передать значение email, т.к. в коде JS именно
на это и ошибка. При ручном составлении URL и перехода по нему — успешное возвращение
хэша и содержимое страницы следующее:




Авторизация проходит успешно. После доступен профиль пользователя.
    


Ответы

Ответ 1



Только что написал рабочий код авторизации во ВКонтакте — http://pastebin.com/5YecKuUs Только учтите, каптча не поддерживается, поэтому сами уже её добавьте. Тест успешно пройден на моём тестовом аккаунте ;)

Ответ 2



Есть рабочая библиотека для PHP, которая получает куку remixsid.

Ответ 3



По состоянию на июль 2018 это рабочий код. Авторизация через мобильную страницу т.к. проще. $email = "{ТЕЛЕФОН}"; $pass = "{ПАРОЛЬ}"; $auth_url = "https://m.vk.com"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $auth_url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); //файл для сохранения кукис - cookie.txt curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //получаем содержимое формы авторизации (URL атрибута action) $login_page = curl_exec($ch); curl_close($ch); //парсим страницу... $html = str_get_html($login_page); //..и узнаем урл авторизации (использовал библиотеку Simple PHP DOM Parser) $login_url = $html->find("form",0)->action; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $login_url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); //отправляем ПОСТ запрос curl_setopt($ch, CURLOPT_POST, 1); //следуем за редиректом curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); //данные запроса curl_setopt($ch, CURLOPT_POSTFIELDS, ["email"=>$email, "pass"=>$pass]); //СНАЧАЛА ЧИТАЕМ КУКИ полученные в первом запросе curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt'); //потом ДОБАВЛЯЕМ НОВЫЕ curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_exec($ch); curl_close($ch); //пользователь авторизован //далее тестируем $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://vk.com/groups?act=catalog"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); //только читаем куки curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $page = curl_exec($ch); curl_close($ch); //если ваш сервер работает на UTF-8, в отличие от VK (windows-1251) echo iconv('windows-1251','utf-8',$page);

Ответ 4



Попробуйте закодировать функцией urlencode

НОД чисел на отрезке

#алгоритм


Как можно реализовать дерево отрезков для ответа на запрос НОД на отрезке так, чтобы
время работы каждого запроса составляло O(log n + log C), где C - максимальное значение?
    


Ответы

Ответ 1



Доработанный алгоритм: Массив элементов дополняется до степени двойки, фиктивные элементы заполняем нулями. Дополняем функцию НОД правилом НОД(a,0)=a. В узлах храним не НОД, а код. Для вычисления кодов узлов сначала на проходе снизу вверх записываем НОД в родительские узлы, потом на проходе сверху вниз на место НОД записываем коды дочерних узлов, вычисляемые как отношение НОД узла (или значения элемента) к произведению родительских кодов. При такой структуре истинное значение НОД каждого узла (в том числе - значение "нижнего" элемента) будет равно произведению кодов самого узла и всех родительских узлов. Код корневого узла равен НОД всех элементов отрезка. Отработка запроса НОД подотрезка ведётся путём корректировки кодов пограничных узлов снизу вверх. Узел считается пограничным, если среди его потомков содержатся как внешние, так и внутренние узлы. При отработке запроса НОД код пограничного узла умножается на код пограничного (либо внутреннего) дочернего узла. Узел считается крайним, если оба его дочерних узла пограничные. Код крайнего узла вычисляется как НОД от кодов дочерних узлов. Корректировка кодов завершается при достижении крайнего либо корневого узла. НОД подотрезка равен коду корневого узла либо произведению кода крайнего узла на коды его родительских узлов. Схему вычислений иллюстрирует рисунок Обработка каждого подотрезка ведётся только вдоль его границ. Это позволяет говорить о требуемой эффективности алгоритма.

Ответ 2



Собственно сам НОД в узлах и хранить. При подъёме использовать сужающий метод, т. е. для левого края в случае левой вершины поднимаемся, в случае правой считаем функцию для неё и предка следующей; для правого края аналогично симметрично.

Как отцентрировать изображения Owl Carousel?

#javascript #html #jquery #slider #карусель


Есть карусель с изображениями различного размера. Как их отцентрировать внутри карусели?
У меня не получается... 

UPD. Отцентрировать и по вертикали, и по горизонтали.

http://jsfiddle.net/8bJUc/524/



$(document).ready(function() {
  $("#owl-demo").owlCarousel({
    navigation: true,
    pagination: true,
    lazyLoad: true
  });
});
@import url('//cdnjs.cloudflare.com/ajax/libs/owl-carousel/1.3.3/owl.carousel.css');
@import url('//cdnjs.cloudflare.com/ajax/libs/owl-carousel/1.3.3/owl.theme.css');

#owl-demo .owl-item > div {
  padding: 0px 2px;
  display: table;
}
#owl-demo .owl-item > div img {
  display: block;
  width: 100%;
  display: table-cell;
  vertical-align: middle;
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  border-radius: 3px;
  margin-bottom: 4px;
}







    


Ответы

Ответ 1



Owl Carousel создаёт дополнительные блоки внутри вашей вёрстки. Поэтому, чтобы правильно добавить CSS свойства, надо работать вот с такой структурой: То есть, таблицей делаем .owl-wrapper, а ячейками — .owl-item. И на все элементы карусель навешивает атрибут style. Например, у блока с классом .owl-wrapper там прописывается display: block;. Поэтому в своих стилях приходится добавить !important. Чтобы сработало вертикальное центрирование по ячейкам таблицы, нужно перебить им свойство float. Ну а для горизонтального центрирования достаточно text-align: center;. Приятно, что в этом решении высота карусели не скачет, когда самая высокая картинка уезжает за пределы экрана. Проверьте результат: http://jsfiddle.net/glebkema/yqfwzkL0/ $(document).ready(function() { $("#owl-demo").owlCarousel({ navigation: true, pagination: true, lazyLoad: true }); }); @import url('//cdnjs.cloudflare.com/ajax/libs/owl-carousel/1.3.3/owl.carousel.css'); @import url('//cdnjs.cloudflare.com/ajax/libs/owl-carousel/1.3.3/owl.theme.css'); #owl-demo .owl-wrapper { display: table !important; margin-bottom: 4px; padding: 0px 2px; } #owl-demo .owl-item { display: table-cell; float: none; vertical-align: middle; } #owl-demo .owl-item > div { text-align: center; } #owl-demo .owl-item img { -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; }

Ответ 2



http://owlgraphic.com/owlcarousel/demos/autoHeight.html Попробуй так свои стили что сейчас можешь убрать а использовать только #owl-demo .owl-item img{ display: block; width: auto; margin: 0 auto; }

Когда может понадобиться самому загружать классы в java?

#java #jvm #classloader


Помогите пожалуйста разобраться с динамической загрузкой классов в java. Как я понимаю,
при старте программы загружаются классы из rt.jar, потом загружается главный класс,
а все остальные пользовательские классы загружаются по мере необходимости (например
класс A загружается только когда в программе создается объект класса A).
Первый мой вопрос заключается в следующем: что собственно значит "JVM загружает класс"?
Имеется в виду что в этот момент происходит компиляция класса?
Так же мне интересно, зачем JVM загружает класс, когда используется его статический
метод? Я провел небольшой эксперимент: написал класс, в котором есть один статический
метод и несколько нестатических. 

public class StExmp {
static{
    c = 5;
}
private int a;
public int getA() {
    return a;
}

public void setA(int a) {
    this.a = a;
}

public int getB() {
    return b;
}

public void setB(int b) {
    this.b = b;
}

private int b;
private static int c;

public StExmp(int a, int b){
    this.a = a;
    this.b = b;
    c = 5;
}

public static void show(){
    System.out.println(c);
}
}


Вызываю статический метод в главном классе StExmp.show();, потом запускаю программу
с флагом -verbose:class и вижу что когда программа дошла до вызова этого метода, она
загрузила весь класс. А почему нельзя загружать только статические члены класса? Ведь
получилось что из-за вызова одного маленького метода пришлось загрузить весь класс,
хотя он больше никак и не используется.
И главный вопрос: Когда может потребоваться самому загружать классы? Например с помощью
ClassLoader.loadClass()? Вот этого я совсем не могу понять. Ведь если мы загружаем
какой то класс, значит мы собираемся его как то использовать? Почему тогда нельзя просто
использовать его в программе (например, создать объект) JVM же сама его загрузит. А
когда это может потребоваться делать методом ClassLoader.loadClass()?
    


Ответы

Ответ 1



Ну и топик. Про загрузку классов можно много чего написать. Тема интересная, правда, уже 100 лет теорией не занимался. В контексте треда, пожалуй, отвечу на вопросы конкретные. Если в чём-то не прав, поправляйте, критика приветствуется. Первый мой вопрос заключается в следующем: что собственно значит "JVM загружает класс"? У вас есть скомпилированные байт коды классов, ClassLoader их грузить по мере необходимости. Зачем нам держать в памяти класс, если он не используется? Класс будет загружен только в момент использования. Точно так же, если на класс не осталось никаких ссылок, то ClassLoader может выгрузить класс из памяти при проходе GC. Имеется в виду что в этот момент происходит компиляция класса? Ваши классы уже скомпилированы javac. ClassLoader в память его грузит. Это если в 2-х словах, на самом деле там происходит верификация байт-кода и т.п. Так же мне интересно, зачем JVM загружает класс, когда используется его статический метод? Статически метод, константы - это метаданные класса. Не представляю, как их можно загрузить в отрыве без класс. А почему нельзя загружать только статические члены класса? Ведь получилось что из-за вызова одного маленького метода пришлось загрузить весь класс, хотя он больше никак и не используется. Предположим, есть у вас: public class StExmp { public static void show(){ System.out.println(c); } } Ок, давайте методом рассуждения выведем необходимость грузить класс. Вы хотите, чтобы метод show был загружен без класса. Но ведь в коде вы потом вызываете метод как StExmp.show()? Если класс не загружен, как вы себе представляете вызов метода? Ну хорошо, предположим загрузчик метод добавить в какую-то общую таблицу виртуальных методов. А потом вы создадите класс: public class StExmp2 { public static void show(){ System.out.println(c); } } Метод show загрузчик так же добавит его в общую таблицу статических методов? Проблему уже видите? Как потом при вызове StExmp2.show() понять какой из этих методов вызвать? Когда может потребоваться самому загружать классы? Например с помощью ClassLoader.loadClass()? Вот этого я совсем не могу понять. Ведь если мы загружаем какой то класс, значит мы собираемся его как то использовать? Почему тогда нельзя просто использовать его в программе (например, создать объект) JVM же сама его загрузит. А когда это может потребоваться делать методом ClassLoader.loadClass()? Например, у вас high-load проект. Приложение должно работать непрерывно. Но вам понадобилось заменить реализацию какого-то метода. Не перезапускать же всё приложение? Если оно стетйтлесс, то ещё ладно, но если там в памяти много данных/кэш и т.п.? Можно заменить налету. Когда это надо? Ну, скажем, вы хотите поправить какой-то критический баг, оптимизировали метод и т.п. Тут можно много чего придумать. К примеру у вас игра, в которой есть возможность добавлять кастомных npc. Вы просто пишите новые класс, который в рантайме подтягивается. Или просто неизвестно какой класс будет использоваться в итоге, решение принимаете в рантайме и грузите необходимый класс. Бывает случаи, когда классы хранятся в базе (да-да, бывает такое). Их иначе и не загрузить вовсе.

Ответ 2



Итак. По умолчанию класслоадеров всего три но вам никто не мешает определять свой. Вам никто не мешает грузить классы не из jar или из файлов, а из БД или вообще через HTTP. Каждый новый класслоадер работает в своем неймспейсе, потому они могут загружать классы с одинаковым именем, но с абсолютно разным содержимым. В качестве "простого" примера: Определим интерфейс Meower, чтоб не мучаться с рефлекшном: package pkg; public interface Meower { String meow(); } package pkg; И вот такую вот конструкцию: public class Main { static String CLASS_NAME = "Cat"; static String CLASS_V1 = "package pkg;\n" + "\n" + "public class Cat implements Meower {\n" + " public String meow() {\n" + " return \"Meo..ow\";\n" + " }\n" + "}\n"; static String CLASS_V2 = "package pkg;\n" + "\n" + "public class Cat implements Meower {\n" + " public String meow() {\n" + " return \"Mrr, meo..ow\";\n" + " }\n" + "}\n"; public static void main(String[] args) throws Exception { // Делаем из строки SourceFile SourceFile srcv1 = new SourceFile(CLASS_NAME, CLASS_V1); SourceFile srcv2 = new SourceFile(CLASS_NAME, CLASS_V2); // Компилируем и загружаем ClassLoader clrv1 = new MemoryClassLoader(srcv1); ClassLoader clrv2 = new MemoryClassLoader(srcv2); // Берем наш класс Class clazzv1 = (Class) Class.forName("pkg." + CLASS_NAME, true, clrv1); Class clazzv2 = (Class) Class.forName("pkg." + CLASS_NAME, true, clrv2); // Инстанцируем экземпляры Meower ov1 = clazzv1.newInstance(); Meower ov2 = clazzv2.newInstance(); // Мяукаем System.out.println(ov1.meow()); // Meo..ow System.out.println(ov2.meow()); // Mrr, meo..ow } } Иными словами, немного помучавшись и дописав какую-нибудь Factory я смогу(хоть и не рекомендую этого делать :)) в рантайме, без остановки JVM, брать исходники откуда-нибудь, компилировать их на ходу и менять поведение остальной программы. Также, учитывая сказанное выше, можно придумать еще несколько причин вызвать Class.forName, наиболее распространенный - заранее прогрузить, а не затормозить когда вызовут. Менее распространенный - если вы грузите не с локальной файловой системы и хотите убедиться заранее что класс доступен. ПС: исходники MemoryClassLoader и SourceFile я сюда не выкладываю чтоб не получилась портянка, но они легко гуглятся.

Как покрыть тестами конструктор класса в java?

#java #intellij_idea #юнит_тесты #test_driven_development


Есть код, который по алгоритму Эвклида находит наибольший общий делитель. 

import java.util.Scanner;

/**
 * Created by user on 24.11.2015.
 * По данным двум числам 1 b) {
                return Euclid(a % b, b);          //рекурсивно вызовется             
            } //  алгоритм, если будет остаток от деления большего              
                                    
            if (b > a) {       //  числа на меньшее и наоборот    
                return Euclid(a, b % a); 
            } else return Euclid(a % b, b);

        }
    }
        public static void main(String[] args) {

        Scanner sc1 = new Scanner(System.in);      //ввод с клавиатуры 
        Scanner sc2 = new Scanner(System.in);
        int a = sc1.nextInt();
        int b = sc2.nextInt();
            System.out.println(Euclid(a,b));
    }
}


Несмотря на то, что программа работает, я решил по практиковаться на ней в разработке
через тестирование. 

Пишу тест: 

import org.junit.Test;

import static org.junit.Assert.*;
public class EuclidTest {

    @Test
    public void testEuclid() throws Exception {

        int result = new Euclid(234, 45); //в этой строке ошибка компиляции 
        assertEquals(9, result, 1e-9);
    }
}


В строке, где я объявляю result мне показывает ошибку компиляции.
 

Когда я переписал класс, заменив конструктор методом с другим названием всё прошло
как по маслу. Связи с этим вопросы:


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

    


Ответы

Ответ 1



public static int Euclid(int a, int b) { //конструктор Дело в том, что это у вас не конструктор, а статический метод, возвращающий int. Конструктор был бы такой (он возвращает объект класса Euclid): public Euclid(int a, int b) { //конструктор Вообще, конструктор здесь не нужен никоим образом. Вам не нужно хранить какое-то состояние, так что и объекты создавать незачем. Переименуйте ваш метод euclid с маленькой буквы, как положено по стандарту именования и пишите вот такой тест: import org.junit.Test; import static org.junit.Assert.*; public class EuclidTest { @Test public void testEuclid() throws Exception { assertEquals(9, euclid(234, 45), 1e-9); } }

Как загрузить данные из БД, показывая процесс ProgressDialog'ом

#android


Мне нужно загрузить данные из базы данных в ArrayList, вo втором потоке, сопровождая
выгрузку DialogFragment'ом. При помощи чего это можно сделать?



Хотел сделать через IntentServise, но он не дружит с List'ами (насколько я понял).
Проповал запустить выгрузку во втором потоке, остановивши первый, но ProgressDialog
спит с основным потоком. Даже пробовал сделать все в основном потоке, но ProgressDialog
не успевает запуститься и зависает с основным потоком...
    


Ответы

Ответ 1



Делается это через AsyncTask, примерная схема такая: Создаем класс наследующий от AsyncTask В конструкторе класса создаем ProgressDialog В методе onPreExecute() показываем диалог progressDialog.show(), проводим другие мероприятия - подготовку у чтению БД и проч. В методе doInBackground() организуем чтение данных из БД в цикле и в ходе чтения вызываем this.publishProgress(), который будет вызывать onProgressUpdate() (см. ниже) В методе onProgressUpdate() увеличиваем счетчик progressDialog.setProgress() В методе onPostExecute() закрываем счетчик progressDialog.dismiss()

Ответ 2



Попробуйте сделать через AsyncTask, у него есть методы onPreExecute и onPostExecute, которые выполняются соответственно, перед и после doInBackground на UI потоке (точнее на потоке, который вызвал execute() у AsyncTask). Показывайте и прячте ваш DialogFragment в этих методах, а загрузку из базы сделайте в doInBackground

Когда выбирать реляционную БД, а когда не реляционную?

#mysql #база_данных #mysqli #nosql


Пишу сайт. Подразумевается большое количество записей разного размера. Подумал о
том, что при большом объёме записей БД будет долго обрабатывать запрос, поэтому надо
её раскинуть на несколько серверов. но вычитал, что реляционные БД плохо масштабируются
и для больших объемов данных используют не реляционные.



подВопрос:
Как поступить: пока не заморачиваться над этим и потом, при необходимости, перенести
данные в не реляционную БД ИЛИ выбрать реляционную/не реляционную БД ?
    


Ответы

Ответ 1



Подумал о том, что при большом объёме записей БД будет долго обрабатывать запрос Планирование не может начинаться с "подумал", боттлнеки всегда бывают в иных местах. Реляционки спокойно работают с миллионами записей. поэтому надо её раскинуть на несколько серверов. но вычитал, что реляционные БД плохо масштабируются Тут у меня опять претензия в ту же степь. Вы не знаете, что именно вы вычитали. Они действительно плохо масштабируются из-за того, что (по крайней мере у большинства) есть только одна модель master-slaves, которая упирается в мастер по скорости записи (поправьте, если есть популярные движки с многочисленными мастерами). В любом случае в базе данных не должно быть тяжелых подсчетов - если вы считаете количество записей в БД, то это должно рассчитываться внутри БД и кэшироваться на уровне приложения, если вы рассчитываете аналитику, то тут БД уже ничего считать не должна. В общем, у меня большие сомнения, что вам нужна масштабируемая система. Что до нереляционок, то их нельзя выбрать просто потому что "лучше масштабируются" - их только основных типов четыре штуки под свои задачи (вряд ли вы будете использовать key-value или графовую БД). Что до масштабирования, то есть row-column (т.е. хранение данных практически как в SQL) Cassandra, которая шардит данные по узлам и имеет практически линейную масштабируемость, т.е. добавление сервера в кластер из N серверов обеспечивает практически 100 * (1 / N + 1) процентов прироста производительности. Если есть знание кассандры, то делать проект на чем-то другом я не вижу смысла (единственная претензия - отсутствие готовых утилит для миграций, но это, надеюсь, изменится), классические реляционки как концепция по факту уже умерли - они, конечно, останутся, но в узком применении, и ближайшие N лет их популярность будет снижаться.

Ответ 2



Во первых, выбор типа базы данных мало зависит от количества записей, а от архитектуры приложения, специфики данных и многих других факторов. Во вторых, реляционные базы данных отлично масштабируются. Например Кассандра способна обрабатывать ~2к запросов в секунду и предоставляет горизонтальное масштабирование. По моим наблюдениям в крупных проектах(миллионы записей в день) отдают предпочтение как раз кассандре. В третьих, не все NoSQL базы данных подходят для работы с большим количеством объектов. Тот же RavenDB совсем не подходит для большого количества маленьких записей. Но если объединить большое количество этих маленьких записей в один документ, то эта база прекрасно справится. В целом сама постановка вопроса говорит о том, что вы плаваете в вопросе. Для работы с BigData не достаточно сделать правильного выбора базы данных, нужно еще грамотно реализовать архитектуру. В противном случае у вас будут проблемы даже при использовании самой подходящего инструмента для вашей задачи. Рекомендую почитать литературу посвященную проектированию баз данных.

Ответ 3



Если хочешь всех удивить возьми nosql Если хочешь блеснуть знанием старины возьми сетевую БД Если хочешь получить благодарность с того света от бабушки Ады - возьми иерархическую БД Ну и наконец, если хочешь написать что-нибудь стоящее возьми реляционную БД

правильная сортировка массива по значению

#php #массивы #алгоритм #сортировка


есть массив

        [0] => Array
            (
                [title] => ITEM1
                [id] => 1
                [voites] => 0
            )

        [1] => Array
            (
                [title] => ITEM2
                [id] => 2
                [voites] => 0
            )

        [2] => Array
            (
                [title] => ITEM3
                [id] => 3
                [voites] => 4 // высший рейтинг
            )
         [3] => Array
            (
                [title] => ITEM4
                [id] => 4
                [voites] => 0
            )


нужно отсортировать по полю voites... и нужно, чтобы не нарушался порядок..
например, обычная отсортировка выводит сначала элемент с наибольшим значение в voites(что
и логично), но остальные, у которых это поле равно 0, выводит с конца... сортирую через
usort()... не получается написать к нему cmp функцию

public function srtCMP($a, $b){
  return $b["voites"] - $a["voites"];
}


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

вот так:

        [0] => Array
            (
                [title] => ITEM3
                [id] => 3
                [voites] => 4 // высший рейтинг
            )
        [1] => Array
            (
                [title] => ITEM1
                [id] => 1
                [voites] => 0
            )

        [2] => Array
            (
                [title] => ITEM2
                [id] => 2
                [voites] => 0
            )
         [3] => Array
            (
                [title] => ITEM4
                [id] => 4
                [voites] => 0
            )

    


Ответы

Ответ 1



По сути, имеется две сортировки: по убыванию voites и (при их равенстве) - по возрастанию ключа элемента. Для применения функции usort() надо временно запомнить этот ключ внутри элемента. Например, так: $common = Array( "0" => Array ( "title" => ITEM1, "id" => 1, "voites" => 0 ), "1" => Array ( "title" => ITEM2, "id" => 2, "voites" => 0 ), "2" => Array ( "title" => ITEM3, "id" => 3, "voites" => 4 // высший рейтинг ), "3" => Array ( "title" => ITEM4, "id" => 4, "voites" => 0 ) ); function cmp($a, $b) { if ($a["voites"] == $b["voites"]) { if (end($a) == end($b)) { return 0; } return (end($a) < end($b)) ? -1 : 1; } return ($a > $b) ? -1 : 1; } function add_key(&$item, $key){ array_push($item,$key); } function delete_key(&$item, $key){ array_pop($item); } array_walk($common, 'add_key'); usort($common, 'cmp'); array_walk($common, 'delete_key'); var_dump($common); Результат: array (size=4) 0 => array (size=3) 'title' => string 'ITEM3' (length=5) 'id' => int 3 'voites' => int 4 1 => array (size=3) 'title' => string 'ITEM1' (length=5) 'id' => int 1 'voites' => int 0 2 => array (size=3) 'title' => string 'ITEM2' (length=5) 'id' => int 2 'voites' => int 0 3 => array (size=3) 'title' => string 'ITEM4' (length=5) 'id' => int 4 'voites' => int 0

Ответ 2



А что если просто отсортировать по ключам voites и id? $arr = [ [ "title" => 'ITEM1', "id" => 1, "voites" => 0 ], [ "title" => 'ITEM2', "id" => 2, "voites" => 0 ], [ "title" => 'ITEM3', "id" => 3, "voites" => 4 // высший рейтинг ], [ "title" => 'ITEM4', "id" => 4, "voites" => 0 ] ]; usort($arr, function($a, $b){ if($a['voites'] === $b['voites']) { return (int) $a['id'] < (int) $b['id'] ? -1 : 1; } return (int) $a['voites'] < (int) $b['voites'] ? 1 : -1; }); var_dump($arr); Результат: array(4) { [0]=> array(3) { ["title"]=> string(5) "ITEM3" ["id"]=> int(3) ["voites"]=> int(4) } [1]=> array(3) { ["title"]=> string(5) "ITEM1" ["id"]=> int(1) ["voites"]=> int(0) } [2]=> array(3) { ["title"]=> string(5) "ITEM2" ["id"]=> int(2) ["voites"]=> int(0) } [3]=> array(3) { ["title"]=> string(5) "ITEM4" ["id"]=> int(4) ["voites"]=> int(0) } }

Как прописать редирект в .htaccess если изменился домен?

#htaccess #redirect #домен #mod_rewrite #поддомены


Есть старый сайт на поддомене, например 2015.site.ru

поменяли основной домен site.ru на 2015.site.moscow

теперь нужно чтобы все обращения к 2015.site.ru переадресовывались на 2015.site.moscow

И естественно, не только обращения только к инденсу домена, но и любые другие, например
чтобы http://2015.site.ru/images/pic.gif преобразовывался в http://2015.site.moscow/images/pic.gif

Однако при обращение к основному сайту site.ru не должно быть переадресации на site.moscow
Подскажите пожалуйста, как такое прописать в .htaccess?
    


Ответы

Ответ 1



просто классика. скопировано из ответа: rewriteengine on rewritecond %{HTTP_HOST} ^a\.example\.com rewriterule ^(.*)$ http://b.example.com/$1 [r,l] доп. информация: http://wiki.apache.org/httpd/WhenNotToUseRewrite

Ответ 2



Если ограничиваться только протоколом HTTP, то необходимый редирект можно записать, например, так: RewriteEngine On RewriteCond %{HTTP_HOST} ^2015\.site\.ru$ RewriteRule ^(.*)$ http://2015.site.moskow/$1 [R=301,L] Если надо таким же образом перенаправлять и протокол HTTPS, то правило будет немного посложнее: RewriteEngine On RewriteCond %{HTTP_HOST} ^2015\.site\.ru$ [NC] RewriteCond %{HTTPS} off RewriteRule ^(.*)$ http://2015.site.moskow/$1 [R=301,L] RewriteCond %{HTTP_HOST} ^2015\.site\.ru$ [NC] RewriteCond %{HTTPS} on RewriteRule ^(.*)$ https://2015.site.moskow/$1 [R=301,L] Это правило понятно, но избыточно и сделано слишком прямолинейно. Можно его оптимизировать, убрав повторяющиеся элементы. В результате получится следующее: RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ - [env=protocol:http] RewriteCond %{HTTPS} on RewriteRule ^(.*)$ - [env=protocol:https] RewriteCond %{HTTP_HOST} ^2015\.site\.ru$ [NC] RewriteRule ^(.*)$ %{ENV:protocol}://2015.site.moskow/$1 [R=301,L] Интересно, что мне не удалось найти онлайн-тестер файла .htaccess, понимающий последний вариант. Но "живой" Apache обработал его корректно.

OpenOffice неведомые текстовые поля

#open_office


Понимаю что для профи вопрос покажется детским лепетом, но меня он поставил в тупик.
Я только учусь, и формулировка вопроса без каких либо сносок и объяснений загоняет
в ступор. Есть задание - создать таблицу в документе Writer и в ячейках сделать тестовые
поля, дословно ( В ячейках где пользователь будет вводить собственные данные необходимо
разместить текстовые поля).

Вставить числовое поле - ячейка С1, максимальное значение 1, по умолчанию 1, шаг
значения 1.   
    


Ответы

Ответ 1



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

Введение в Spring

#spring #spring_mvc


Здравствуйте. В общем я хочу познакомится с Spring Framework MVC.. У меня есть знания
Java 8, HTML/CSS, XML. Проблема в том, что у меня не такая структура проекта как в
уроках. Я хочу использовать чисто аннотации для конфигурирования, ну конечно XML, там
где без него никак (конфигурирование Maven). Мне сказали скачать Maven, Tomcat. Все
скачал, поставил, переменные прописал и в настройках IntelliJ IDEA 15.1 поставил путь
к Maven. Spring MVC скачал как зависимость, (New -> Project... -> Spring -> Spring
MVC). Создал.. В итоге у меня такая структура проекта: 



Нет pom.xml... Я не пойму почему, ведь все подключено и указано. Ну ладно, это поправимо
через Add Framework Support -> Maven, и добавляется pom.xml . Но содержимое сильно
отличается от того, что в уроках по Spring. 
Пробовал эти уроки: https://www.youtube.com/watch?v=YN66kDMjnYM , вроде без конфигурирования
Spring'a через XML, но для меня там все сложно.. Для меня это как темный лес, человек
уже сразу на готовом проекте показывает, а я его ещё не создал толком даже. Вот уже
два дня сижу и не могу Hello World сделать, везде либо XML, либо у меня что-то в структуре
не так (да, по большей части это проблемы с моими руками, наверное). Что я хочу:


Что с этим Maven'ом ? Где pox.xml автоматически созданный?
Можете кто-то, пожалуйста, скинуть просто Spring MVC веб-приложение
(типичный Hello World) по самым новым стандартам.. Ну так как сейчас
пишут на Spring MVC..
Есть какие-то уроки, даже пусть на английском (туториалы), где все
на аннотациях и, как бы сказать, "по-современному", в том тоне, что
сейчас популярен и востребован. Поделитесь пожалуйста.
У меня минимальные знания ВЕБ'а. Правильно ли я понял: На Spring MVC
мы пишем веб-приложение (сервер), который в свою очередь работает с
помощью Java сервлетов. Потом страница на HTML/CSS с помощью
JavaScript обращается к нашему веб-приложению (серверу). На самом
Spring MVC мы не занимаемся написанием непосредственно страницы
(HTML/CSS) или все же занимаемся, иначе для чего JSP (а этот
разновидность HTML). Пролейте свет сюда.


Вопросы не очень грамотные, местами глупые, сразу прошу извинить. 
    


Ответы

Ответ 1



Его там не будет. Для того, чтобы он там был, надо создавать maven-проект с архетипом spring-mvc (название может быть другим). Первый результат поисковика по spring mvc annotation example Эти уроки называются официальная документация. Но она большая, поэтому можешь попробовать так. Вроде да, но нет. Первый делом браузер идет с GET-запросом к серверу, с просьбой дать ему страницу. Тут можно отдать статическую страницу (HTML+javascript), а потом через javascript запросить у сервера динамические данные. Либо сгенерировать её при помощи того же JSP, и отдать сгенерированный html-контент. Spring как раз таки содержит такую штуку, которая из JSP может сделать HTML. Можно также использовать гибридный подход. Тут дело предпочтения. Изучать spring сразу не стоит точно. Сначала стоит изучить обычные сервлеты.

Интеграция SQL с .NET

#net #sql_server #sqlclr


Необходимо реализовать некоторый функционал обработки данных SQL сервера при помощи .NET.

По ключевым словам "Интеграция .NET и SQL" находятся, в первую очередь, описания
"SQL CLR". Попробовал сие, и столкнулся с рядом серьезных проблем, которые не позволяют
его использовать:


Сложности в регистрации .NET сборок на SQL сервере. А именно: я использую сторонние
библиотеки. Во время их регистрации указывается об необходимости регистрировать system.servicemodel.
Если пытаюсь регистрировать system.servicemodel, необходима регистрация сборки system.servicemodel.internals,
а этой сборки я не нахожу. 
Зависимость версии сервера от версии .NET: Sql сервер версии 2008 использует .NET
до версии 3.5, соответсвенно сторонние сборки тоже должны быть скомпилированы в версиях
не старше 3.5. Мною используемые библиотеки доступны только в версии 4.0. Таким образом
отпадает возможность их использования в версиях SQL сервера до 2008. Для меня слишком
критично.


Итак, меня интересуют другие доступные способы интерации .NET и SQL.

Во время проб SQLCRL возникла идея использовать WCF сервис из пользовательских SQL
функций. Таким образом я бы мог всю "грязную" работу (и зависимости от сторонних библиотек)
переложить на сторону сервиса, а в контракте использовать лишь простые структуры данных.
Сервис должен тогда работать локально и испльзовать самое быстрое бинарное соединение
(возможно pipe).

Как вам такая идея? Может быть существуют другие способы, попроще?

Спасибо за советы.
    


Ответы

Ответ 1



Идея использовать SQLCLR для описанного сценария может казаться привлекательной, но имеет свои минусы, и для описанной задачи есть другие решения. Основные минусы SQLCLR Основной минус это maintainability проекта, использующего подобную интеграцию, и здесь Вы уже столкнулись с некоторыми трудностями. Плюс SQLCLR Плюс SQLCLR может быть в том, можно избежать многочисленных внешних запросов к SQL для представления данных из реляционных таблиц в структурированном виде для компоненты обработки. Способ проще Это собственно основной способ интеграции .NET и SQL, где есть клиент .NET, и сервер SQL, а не наоборот, как в случае SQLCLR. Сбор структурированных данных из реляционных таблиц в этом случае можно выполнить с помощью for xml с подзапросами. Заметьте, что в случае вызова внешней компоненты обработки изнутри SQL, и записи полученного ответа в таблицу, данные передаются два раза: туда - сериализованных документ, обратно - бинарные данные PDF. В случае вызова SQL для получения структурированных данных, и отправки для сохранения обратно - точно такие же по смыслу данные, в тех же самых направлениях. То есть, в терминах обмена сообщениями в межпроцессном взаимодействии, будет следующее: (Запрос из SQL в .NET): SQL -> Cтруктура -> NET (1) (Ответ из .NET в SQL): NET -> PDF -> SQL (2) Либо: (Запрос из .NET в SQL): NET -> id документа -> SQL (дешево) (Ответ из SQL в .NET): SQL -> Cтруктура -> NET (1) (Запрос из .NET в SQL): NET -> PDF -> SQL (2) (ОК от SQL) : SQL -> OK -> NET (дешево) Видим, что основной обмен сообщениями (1, 2) остается таким же в обоих случаях. Компромисс Есть и компромиссный вариант, где SQLCLR все же будет использоваться, но только в ограниченном варианте - только для сериализации контракта. for xml может оказаться неудобным по каким то причинам, например - если уже есть оговоренный формат сериализации, который удобнее реализовать средствами .NET. Этот вариант поможет пользоваться удобством программирования на .NET, возможно - повторно использовать код сериализации контракта, а так же поможет избежать зависимости от компонент, которые накладывают свои технологические ограничения. Молоток побольше Судя по комментариям, для автора важно, чтобы SQL Server стал точкой интеграции нескольких систем, поэтому стоит посмотреть в сторону очередей Server Broker. Service Broker в частности поддерживает активацию внешних процессов. Типовые варианты использования компонента Service Broker https://technet.microsoft.com/ru-ru/library/ms166071(v=sql.105).aspx

Ответ 2



После некоторых экспериментов хотел бы поделиться своим опытом. Я продолжил развивать идею обработки данных при помощи локального сервиса WCF. Сделал небольшое тестовое приложение. Сразу скажу, что использовать WCF в смысле "Service Reference" (соврменный .NET клиент для WCF служб) не получилось: основные проблемы возникли при регистрации различных сборок, которые не входят в число поддерживаемых. Кроме того, необходимо четко определять и разделять версии сборок .NET и SQL Servera, битность системы, битность сервера. Кроме того смешанные сборки (которые содержат чистый управляемый код и неуправляемый) не могут быть зарегестрированы на сервере. Долго бился - очень сложно. Зато испльзовать WCF как "Web Refernece" (устаревший, но еще доступный вариант, который основывается на .NET 2.0) вполне получилось. В этом случае привязка "NamedPipes", как я хотел, недоступна - можно задействовать лишь HttpBasic. Но тем не менее - работает! Кроме того, не понадобилось регистрировать какие-то дополнительные сборки .NET. Но потребовалось создание дополнительной сборки сериализации для моей сборки (в интрене легко нагуглить, что это, как и почему) - содержит инструкции относительно сериализции, которые в нормальной обстановке генерируются налету, но в ограниченной SQL.NET среде должны быть представленны явно. Ну и, ясно, что никаких app.config SQL Server не понимет, поэтому вся конфигурация у меня прописана жестко в коде (для хранения настроек можно было бы использовать сам SQL server). Также были проблемы при передачи на WCF сервис больших байтовых массивов - WebReference-Клиент не имеет настроек типа MaxMessageSize. Такое решил с помощью чанкинга - передачи данных небольшими порциями. SQL Service Database Project содан для целевой платформы 3.5, без проблем выполняется и на SQL Server 2008 R2 и на SQL Server 2012.

Ответ 3



Вот еще одно решение, которое я бы хотел в кратце изложить и по-возможности узнать мнение специалистов, т.к. я не знаком в достаточной мере с используемой технологией: Com+. По сути, решение не отличается от того, которое использеут локальную Web-службу. Только ей на смену приходит COM+ сервис. COM+ сервис пишется на .NET, использует необходимые сторонние библиотеки, наружу торчит интерфейс, оперирующий простыми типами. [JustInTimeActivation] public class Class1 : ServicedComponent, Interface1 { [AutoComplete] public byte[] MyMethodName(byte[] inputData, string ext ) { // ... } } SqlCLR-функция обращаятся к COM+ службе при помощи рефликции: Type customType = Type.GetTypeFromProgID("ClassLibraryCom1.Class1"); Object customObj = Activator.CreateInstance(customType); Object objValue = customType.InvokeMember("MyMethodName", BindingFlags.InvokeMethod, null, customObj, new Object[] { param1, param2 } ); Данный подход я испробовал на небольшом теством проекте - выполнение ощутимо быстрее чем веб-сервис, хоть и рефлексия (насколько быстрее - пока неясно, нужно замерять). Расход памяти - примерно такой же.

Не работает lambda функция при печати случайной буквы из списка

#python #случайные_числа #lambda


import random
print(lambda upletters: (random.choice(['Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M'])))


Возможно синтаксис не корректен. Помогите разобраться.
    


Ответы

Ответ 1



Если вы хотите использовать лямбду в точке объявления, именовать её не надо. Более того, код вида lambda upletters : ... объявляет лямбду с параметром upletters. Для использования лямбды "на месте" её нужно вызвать следующим образом: (lambda : ...)() Таким образом, корректный код в данном случае имеет следующий вид: import random print( (lambda : (random.choice(['Q','W']))) () ) (Массив сократил для улучшения понимания конструкции.)

Ответ 2



О вопросе: код не выбрасывает SyntaxError, то есть синтаксис корректен. Достаточно запустить код в вопросе, чтобы это увидеть в коде нет явного словаря, поэтому не ясно к чему заголовок "Не работает lambda функция в словаре" относился выражение с lambda также как и def cоздаёт функцию, но не вызывает её upletters -- это агрумент функции в коде (который никак не используется) lambda здесь не нужна, код можно переписать как: import random print(random.choice('QWERTYUIOPASDFGHJKLZXCVBNM')) или для ясности: import random import string print(random.choice(string.ascii_uppercase)) Назначение lambda создание анонимных функций. Если хочется вызывать код по имени, то следует def использовать: import random import string def random_letter(letters=string.ascii_uppercase): """Select a random letter from *letters*.""" return random.choice(letters) print(random_letter()) Функции являются полноценными объектами в Питоне: им можно дать имя, их можно передавать в качестве параметров в другие функции (такие как print()) и тд: random_letter (без скобочек) возвращает саму функцию (объект) random_letter() (со скобками) вызывает функцию (и возвращает букву в данном случае, то есть выражение возвращает строку). Если хочется передать функцию как выражение (без имени), например, в другую функцию f(), то можно functools.partial() использовать, чтобы облегчить интроспекцию: f(functools.partial(random.choice, string.ascii_uppercase)) # instead of `f(lambda: random.choice(string.ascii_uppercase))`

Ответ 3



import random upletters = lambda : (random.choice(['Q','W','E','R','T','Y','U','I','O','P','A','S','D','F','G','H','J','K','L','Z','X','C','V','B','N','M'])) print(upletters()) lambda возвращает функцию

Как не менять строку после выполнения команды bash

#bash


Делаю вывод любой команды bash в файл, после этого делаю вывод следующей команды
в этот же файл. Хочу чтобы результат второго вывода записывался в ту же строку, что
и первый.

Например: 
echo 123 > file
date >> file

чтобы в итоге получилось 123 Вт. дек.  8 14:17:39 MSK 2015

Вывод будет вестись в большом массиве текста, поэтому решение не должно быть универсальным
для любой строки в документе.
    


Ответы

Ответ 1



man echo echo -n "123 " > file echo -n `date` >> file

Ответ 2



Ребят есть же printf... добавили \n вывод на нову строку не добавили идет добавление к строке: ~$ printf "hello" > output_file ~$ printf "world" >> output_file ~$ cat output_file hello world GNU bash https://www.gnu.org/software/bash/manual/bash.html#index-printf

Ответ 3



Можно в одну строку: echo '123 '"`date`" > file

Набор номера мобильного телефона с Android приложения

#android


Есть активити в котором в ListView отображаются заказы,  в каждом заказе есть поле:
номер телефона,  как можно прямо в ListView сделать этот номер ссылкой, при нажатии
на которую - набирался бы номер?

 
    


Ответы

Ответ 1



1)Прописываем в манифесте: 2)Код для звонка Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + yourArrayList.getPosition(position).getPhoneNumber())); startActivity(intent); 3) Выше пример для списка с объектами. Если же у вас каждый элемент это одно текстовое поле со всей инфой, то надо бы передеалть тогда. Ну или как максимум поиграться с subString

Ответ 2



Данный код вам в помощь, а именно флаг android:autoLink="phone" Он задаёт параметр, что в данном TextView может находиться телефон и по его нахождении он будет выделен цветом и будет кликабельным, если будет баговаться, то попробуйте разделить текст на несколько TextView и добавить android:autoLink="phone" только в тот, в котором будет чисто номер телефона написан. Также стоит обратить внимание, что данный флаг может не сработать и телефон может быть не кликабельным, если будет неизвестный формат телефона, поэтому телефоны должны быть адекватного формата, а не fffapoga и что-то подобное

Ответ 3



Самый примитивный способ - это поместить номер в отдельный TextView с специальным стилем(подчеркивание и синий как ссылка), на него повесить OnClickListener,а дальше обычная работа с TelephoneManager(или чем то такими). Посмотри книгу Алексея Голощапова "Google Android Создание приложения для смартфонов и планшетных ПК".

Как получить полный путь к папкам Temp и Application Data

#cpp #windows #winapi


Имеются ввиду системная папка Temp в WINDOWS\ и Application Data (%APPDATA%)
    


Ответы

Ответ 1



%APPDATA% можно получить, например, функцией SHGetFolderPath или getenv из стандартной библиотеки, %TEMP% для текущего пользователя - GetTempPath или та же getenv, а вот для получения системной папки %TEMP% придётся использовать функцию ExpandEnvironmentStringsForUser: #include #include #include #include int main() { TCHAR szPath[MAX_PATH]; char* path; if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, szPath))) { std::cout << "%APPDATA% (SHGetFolderPath) = " << szPath << std::endl; } path = getenv("APPDATA"); if (path != NULL) { std::cout << "%APPDATA% (getenv) = " << path << std::endl; } if (GetTempPath(MAX_PATH, szPath)) { std::cout << "User's %TEMP% (GetTempPath) = " << szPath << std::endl; } path = getenv("TEMP"); if (path != NULL) { std::cout << "User's %TEMP% (getenv) = " << path << std::endl; } if (ExpandEnvironmentStringsForUser(NULL, "%TEMP%", szPath, MAX_PATH)) { std::cout << "System's %TEMP% = " << szPath << std::endl; } return 0; } Для использования ExpandEnvironmentStringsForUser нужно дополнительно прилинковаться к Userenv.dll.

Ревью Архитектуры приложения

#c_sharp #архитектура #шаблоны_проектирования #инспекция_кода


Есть решение разбитое на следующие слои: DAO, DAL, Services Gui где,


DAO - здесь хранятся классы описывающие доменнные модели;
DAL - Generic Repository и его реализация; 
Services - здесь у меня методы по типу следующего: IEnumerable GetEntities();
Gui - клиентская часть


предвижу сразу вопрос чем Services отличается от Repository, в репозитории у меня
базовые методы CRUD:

void Create(Entity entity);
void Update(Entity entity);
void Delete(Entity entity);
IQueryable Table {get;}


в Services же у меня строются более сложные запросы: соединения, группировка например:

var _orders = получаем данные;
var _histories = получаем данные;
var orders = _orders.Join(_histories, o=>o.Id, h=>h.OrderId,(o,h)=>new OrderView
                    {
                        //Формируем необходимое представление
                    })
                    .ToList();


ну и т.п.

зависимости между проектами следующие:


DAO подключен в качестве reference в DAL, Services, Gui
DAL подключен в качестве reference в Services, Gui
Services подключен в качестве reference в Gui


Хочу проект сделать так что бы дальнейшая поддержка причиняла как можно меньше проблем.

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

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


Ответы

Ответ 1



Есть самые разные способы проектирования приложения. Как я вижу вы пытаетесь использовать DDD. Этот паттрен достаточно универсален, но не является сильвербуллетом, а так же имеет очень много вариаций реализации, например CQRS+ES или DDD+Onion которые имеют свои назначения, а вместе с ним свои плюсы и минусы. По мимо DDD и его вариаций, существуют такие архитектурные паттерны как EDA, SOA, NLayer и другие. Что бы поддержка не причиняла больших проблем, нужно сначала выбрать правильную архитектуру, а это вопрос не только правильного выбора паттерна, но языка, стека технологий и многого другого. Сам же выбор зависит от решаемой задачи и различных условий.

Ответ 2



Был у меня опыт разработки именно при такой архитектуре, только за место Entity Framework использовался NHibernate. Ну и был еще один дополнительный слой абстракции для веб сервисов. То бишь было параллельно несколько веб сервисов, которые пользовались фунциями из слоя Services. В целом код получался весьма читабельным и понятным. Но вместе с этим при реализации функции в GUI приходилось протягивать эту функцию через все слои это со временем начинало бесить. Получалось как-то слишком много лишнего кода который приходилось писать лишь из-за всех этих слоёв. Дебаг так же происходил чуть медленнее. Были некоторые трудности с определением того куда стоит засунуть функцию, в DAL или Services. В целом считаю данную архитектуру весьма адекватной для решения многих задач. Она предлагает высокую степень гибкости и читабельности, но может стать очень громоздкой. Что бы избавиться от громоздкозти этого монолита мне кажется, можно было бы начать отщипывать от монолита микросервисы.

Как в объект передать зависимость, минуя методы и свойства этого объекта?

#c_sharp


Есть следующие типы в пространстве имен:

namespace Model {
   public interface IData {
      void Send(string str);
   }
   public class Test {
      public void Run() {
        // (1)
      }
   }
}


В методе Test.Run для его работы должна оказаться ссылка на объект с реализацией IData.

Есть следующая реализация интерфейса IData и код для работы с Test.

class Data : Model.IData {
    public void Send(string str) { }     
}     

var d = new Data();
var t = new Test();

// (2) 


Какой код должен быть вместо (1) и (2), чтобы в Test.Run оказалась ссылка на Data?
При этом в определении класса Test нельзя что-либо менять, нельзя добавлять конструктор(ы),
методы, свойства и поля, и нельзя менять сигнатуру метода Run.

Также нельзя использовать Singleton.

p.s.
Это не для "размять мозги", как сказали в комментах. Есть огромное количество кода.
И есть просто драконовский анализатор кода. Добавлять/менять правила в анализаторе
не будут. Код Model менять нельзя и синглтоны исключены, а в Test.Run надо добавить
зависимость. На вопрос, - как? Ответили, - как хотите так и делайте. 
Если есть идеи - напишите как, а не минусуйте вопрос.
    


Ответы

Ответ 1



Вот рабочий пример с thread local storage: namespace Model { public interface IData { void Send(string str); } public class Test { public void Run() { LocalDataStoreSlot slot = Thread.GetNamedDataSlot("dict"); var dict = (Dictionary)Thread.GetData(slot); var d = dict[this]; } } } namespace ThreadLocalTest { class Data : Model.IData { public void Send(string str) { } } class Program { static void Main(string[] args) { var d = new Data(); var t = new Model.Test(); LocalDataStoreSlot slot = Thread.AllocateNamedDataSlot("dict"); var dict = new Dictionary(); Thread.SetData(slot, dict); dict[t] = d; t.Run(); Thread.FreeNamedDataSlot("dict"); } } } По поводу других возможных опций, вот ещё: http://blog.stephencleary.com/2013/04/implicit-async-context-asynclocal.html (это пригодится, если вы хотите протащить контекст через границу await).

Ответ 2



В порядке дурацкого предложения. Создаём новый класс, который слушает сетевой порт. В конструктор передаём адрес объекта типа Data. В Test.Run подключаемся к порту и получаем адрес. Можно также использовать вместо сетевых соединений pipe или класть адрес в файл с фиксированным расположением.

Как последовательно выбирать данные из массива?

#php


Есть скрипт, который заполняет базу данных данными, взятыми из массива. Сейчас данные
с массива, добавляются случайно, как можно изменить скрипт чтобы данные добавлялись
последовательно (Один, Два, Три,..,.., Один, Два,.......)?

Php:

if(100==100){

$rowsToCreate = 30;

$name = array("Один", "Два", "Три", "Четыре", "Пять");
$text = array("Текст 1", "Текст 2", "Текст 3", "Текст 4", "Текст 5");

do {
    $name2 = $name[array_rand($name)];
    $text2 = $text[array_rand($text)];

    $data = "INSERT INTO `blog` (id, name, text) VALUES (NULL, '".$name2."', ' ".$text2."'
) "; 

    $Result = mysql_query($data);
    $rowsToCreate--;
} while ($rowsToCreate>=1);


    if ($Result) {
        echo "

Информация добавлена!!

"; }else{ echo "

Увы, но информация не добавлена!!

"; } } Бд: CREATE TABLE IF NOT EXISTS `blog` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL, `text` varchar(100) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;


Ответы

Ответ 1



Вот так подойдет? $inArrayCnt = 0; // здесь будем хранить порядковый номер записи из массива do { $name2 = $name[$inArrayCnt]; $text2 = $text[$inArrayCnt]; $data = "INSERT INTO `blog` (id, name, text) VALUES (NULL, '".$name2."', ' ".$text2."' ) "; $Result = mysql_query($data); $rowsToCreate--; $inArrayCnt++; // увеличиваем порядковы номер if ($inArrayCnt==Count($name)) $inArrayCnt=0; // если новый номер последний - обнуляем счетчик } while ($rowsToCreate>=1);

PHP: Вставить пробел каждые N символов но начиная с конца

#php #строки


Как вставить пробел на РНР каждые N символов но начиная отсчет не с начала строки
а с конца. Например чтобы с 1234567 получить 1 234 567 (если каждые три символа). chunk_split
и wordwrap работают лишь со значениями больше 0

Можно в принципе вот так:

$reverse = strrev("1234567");
$withSpaces = chunk_split($reverse, 3, ' ');
echo strrev($withSpaces);


Но может есть что то проще
    


Ответы

Ответ 1



number_format Если вкратце: Вводимое число Сколько символов после "точки" Разделитель "точки" Разделитель тысячных (каждый третий с конца) Пример: echo number_format(1000000, 0, '.', ' '); // 1 000 000 echo number_format(1000000, 2, '.', ','); // 1,000,000.00

Можно ли и как программировать AVR микроконтроллер (attiny13) силами самого микроконтроллера?

#avr


Т.е. задача такая, иметь возможность с помощью кнопок, подключенных к микроконтроллеру,
запрограммировать его без перепрошивки и без написания интерпретатора (первое, что
пришло в голову - fort). Т.е. сохранить и вызвать функцию в которой используется ограниченный
набор команд, принимается один числовой параметр и возвращается один числовой параметр.
Спасибо!

Пояснение

Необходимо:


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


Примером самой простой подпрограммы может быть: var + 1. 
    


Ответы

Ответ 1



Ответ ДА :) Сам не пробовал. Фрагмент статьи с хабра Самым распространенным и удобным интерфейсом для прошивки AVR является SPI (Serial Peripheral Interface). Для подключения по SPI нужно всего четыре провода, не считая земли: SCK — тактовый сигнал, синхронизирует все операции обмена данными; MOSI (Master Out Slave In) — линия данных от ведущего устройства к ведомому; MISO (Master In Slave Out) — линия данных, наоборот, от ведомого устройства к ведущему; RESET — для разрешения прошивки по SPI нужно подать логический «0» на этот вывод. Схема: кнопки от VCC на пины Reset, Mosi, Sck, после нажатия подтянуты к земле резисторами. Пин GND на землю, с пина Miso светодиод с резистором на землю. Режим программирования включается подачей «0» на ногу RESET. Но есть некоторые тонкости. Atmel рекомендует сначала выставить на выводах RESET и SCK низкий уровень, а только потом подавать на контроллер питание. Если такой возможности нет, нужно после включения питания подать «0» на SCK, а затем положительный импульс на RESET Далее нужно передать команду на собственно включение режима программирования: 10101100 01010011 xxxxxxxx xxxxxxxx Биты, обозначенные как x, могут быть любыми. Во время передачи третьего байта контроллер должен переслать обратно второй байт (01010011). Если это произошло, значит, все хорошо, команда принята, контроллер ждет дальнейших инструкций. Если ответ отличается, нужно перезагрузить МК и попробовать все сначала. Сначала необходимо загрузить данные в буфер страницы, для этого используется команда «Load Program Memory Page» 01000000 000xxxxx xxxxbbbb iiiiiiii — для загрузки младшего байта слова, и 01001000 000xxxxx xxxxbbbb iiiiiiii — для загрузки старшего. 4 младших бита 3-го байта команды bbbb — адрес слова на странице, iiiiiiii — загружаемый байт. Сначала всегда должен загружаться младший байт слова, а затем — старший байт того же слова. После того, как буфер страницы загружен, нужно выполнить команду «Write Program Memory Page» 01001100 0000000a bbbbxxxx xxxxxxxx для записи страницы непосредственно в память контроллера. Младший бит второго байта и старшие 4 бита третьего a:bbbb — пятибитный номер страницы для записи. Лучше в подробностях смотреть по ссылке. На случай необитаемого острова распечатать даташит, заламинировать, хранить с собой.

Ответ 2



Можно. Смотрите в даташите раздел Self-Programming the Flash. Но, если нет ограничений, удобнее будет взять мк с большим кол-вом памяти. Ваш "интерпретарор" проще будет вместить:) Хотя задача безусловно интересная и полезная

Ответ 3



Можно, но очень сложно. Необходимо заносить программу вручную нулями и единичками. Проще arduino nano взять или другой микроконтроллер.

Ответ 4



У ATTiny13 очень мало памяти для таких подвигов - лучше используйте МК с бОльшим объёмом памяти или внешнюю eeprom. Тогда, по сути, Вам нужно будет только читать программу по SPI или I2C из EEPROM. Транслятор будет получать например, по 2 байта, где 1-й байт - это код функции, 2-й байт - аргумент. В таком случае он будет выглядеть как набор if-else или case-switch, или массив указателей на функции. В первом и втором случаях проверяете код функции в заголовках if-else или switch и выполняете заданные в телах условных операторов куски кода. В случае массива указателей на функции просто вызываете функцию, на которую указывает элемент массива под номером, равным коду функции. Как-то так) Для ввода программы можно использовать SPI и самописный протокол типа номер_функции-аргумент.

Как вывести вместо числа название категории Yii2? GridView

#php #yii2 #gridview


Имеется GridView, но категории выведены в виде цифр. Как вывести названия из другой
таблицы - категорий вместо этих цифр по связи Category_id-Title? Очень трудно дается Yii2.



Что мне нужно прописать в коде? Я пробовал по-разному, и тут брал, и тут. Но всё
оканчивалось ошибками. Спасибо за помощь!

    


Ответы

Ответ 1



[ 'attribute' => 'category_id', 'filter' => Html::activeDropDownList( $searchModel, 'category_id', ArrayHelper::map(Category::find()->all(), 'id', 'name'), ['class' => 'form-control'] ), 'value' => 'category.name', ] Вот такой метод ещё работает, на фильтр не обращайте внимания, я про 'value' => 'category.name'. Не знаю красивее ли это, чем в предыдущем варианте, но я сам новенький. Работает так, подскажет может кто из бывалых в чем разница?

Ответ 2



Требуется для начала определить связи в модели, например, у Вас есть модели для таблиц Category и Data, тогда в модели category будет такой метод: public function getData() { return $this->hasOne(Data::className(), ['id' => 'data_id']); } Подробнее тут расжёвано про Active Record. Далее, мы можем непосредственно в GridView настроить собственный столбец: $dataProvider, 'filterModel' => $searchModel, 'columns' => [ [ 'attribute' => 'id', 'value' => function ($model, $key, $index, $widget) { return $model->data->title; }, 'format' => 'raw', ], ], ]); Возможно, я что-то и упустил из виду или не совсем верно понял, что вы хотите добиться, но советую почитать документацию на гитхабе, где всё довольно хорошо расжёвано. Успехов в изучении.

Шутки браузеров: криво работает php валидация?

#php #webbrowser #opera


Я тестирую в основном сайт в Google Chrome (посл. версия), и только что заметил,
что Opera (последняя версия) позволяет обойти ОБЯЗАТЕЛЬНОЕ ТРЕБОВАНИЕ заполнить возраст.
Просто игнорирует это поле и даже успешно отправляется форма и тп.

Ссылка на форму

А также наверно какие-то старые браузеры умудряются еще регать людей с НЕВОЗМОЖНЫМ
значением пола, например.

Т.е. Опера в данном случае игнорит и JS, и PHP валидацию. Это вообще законна такая
работа PHP и браузеров?

Использую rules:

$rules[] = array( 'gender', 'required', 'message' => 'Укажите пол' );
$rules[] = array( 'birthYear', 'required', 'message' => 'Укажите год рождения' );
$rules[] = array('gender', 'in', 'range' => array("f", "m", "?"), 'message' => 'Укажите
пол.');


Обновление

Добавил еще правило:

$rules[] = array( 'birthYear',
            'length',
            'min'=>$AGE_START,
            'max'=>$AGE_END,
            'tooShort' => 'Укажите год рождения',
            'tooLong' => 'Укажите год рождения',
        );


Опера перестала глючить.
    


Ответы

Ответ 1



К вам на сервер от клиента (в данном случае браузер) могут прийти какие угодно данные. Валидация данных всегда должна быть на сервере помимо JS. Если у вас регистрация проходит даже без обязательных полей, значит у вас некорректный PHP код с валидацией. UPD Лучше не обращаться к массиву $_POST напрямую. К тому же, в вашем выпадающем списке есть пустое значение. Один браузер его вам посылает, другой нет. Получается при обращении к $_POST['Form']['gender'] у вас в одном случае строка пустая, в другом случае null (не факт, это моё предположение). Проверьте $_POST массив в контроллере в разных браузерах: var_dump($_POST); die(); Вам может помочь либо метод saveAttributes(), либо как минимум проверка на пустое значение: if(isset($_POST['Form']['gender']) && $_POST['Form']['gender'] != '') { $form->gender = $_POST['Form']['gender']; }

Проверить установку пакета

#java #android


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


Ответы

Ответ 1



Проверка на то, установлено ли приложение: boolean installed = appInstalledOrNot("com.Example.kek"); private boolean appIsInstalled(String uri) { PackageManager pm = getPackageManager(); boolean app_installed; try { pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES); app_installed = true; } catch (PackageManager.NameNotFoundException e) { app_installed = false; } return app_installed; }

Ответ 2



Объявляете в манифесте ресивер: Точно не помню, но возможно нужны какие-то пермишены. И создаете класс public class AppListener extends BroadcastReceiver { @Override public void onReceive(Context context, Intent arg1) { // TODO Auto-generated method stub Log.v(TAG, "there is a broadcast"); } } Теперь в него будут приходить броадкасты об установке и удалении приложений. Чтобы проверить, установлено ли приложение в данный момент: PackageManager pm = context.getPackageManager(); try { ApplicationInfo appInfo = pm.getApplicationInfo("app.package.name", 0); //такое приложение есть } catch (NameNotFoundException e) { //такого приложения нет }

Как добавить файл в 7-zip архив с сохранением структуры каталогов?

#c_sharp #7z


Использую SevenZipSharp.

    SevenZipCompressor.SetLibraryPath("7z.dll");
    SevenZipCompressor szc = new SevenZipCompressor();
    szc.DirectoryStructure = true;
    szc.PreserveDirectoryRoot = true;
    szc.ZipEncryptionMethod = ZipEncryptionMethod.Aes256;
    szc.CompressionMode = CompressionMode.Create;


Если добавить несколько файлов сразу, то каталоги создаются нормально

    szc.CompressFilesEncrypted("test.7z", "123", @"C:\Test\Test2\123.txt", @"C:\Test\Test\123.txt",
@"C:\Test\123.txt");


А если добавлять по одному, то все файлы записываются в корень архива.

    szc.CompressFilesEncrypted("test.7z", "123", @"C:\Test\Test2\123.txt");
    szc.CompressionMode = CompressionMode.Append;
    szc.CompressFilesEncrypted("test.7z", "123", @"C:\Test\Test\123.txt");
    szc.CompressFilesEncrypted("test.7z", "123", @"C:\Test\123.txt");


В итоге получается 3 файла 123.txt в корне.

Что я делаю не так? Как добавлять по одному файлу с сохранением полного пути?
    


Ответы

Ответ 1



Нужно передавать длину общего пути для всех файлов: string commonPath = "C:\\Test\\"; int commonPathLength = commonPath.Length; szc.CompressFilesEncrypted("test.7z", commonPathLength, "123", @"C:\Test\Test2\123.txt"); szc.CompressionMode = CompressionMode.Append; szc.CompressFilesEncrypted("test.7z", commonPathLength, "123", @"C:\Test\Test\123.txt"); szc.CompressFilesEncrypted("test.7z", commonPathLength, "123", @"C:\Test\123.txt"); Судя по исходникам (к сожалению, у проекта нету документации), метод CompressFilesEncrypted отличает часть пути, которая принадлежит архиву, от части пути внутри архива, при помощи вычисления общей части пути всех переданных файлов. public void CompressFilesEncrypted( string archiveName, string password, params string[] fileFullNames) { CompressFilesEncrypted(archiveName, CommonRoot(fileFullNames), password, fileFullNames); } То есть, если переданы файлы C:\Test\Test2\123.txt и C:\Test\Test4\123.txt, то общей частью будет C:\Test\. А вот для одного файла общей частью оказывается весь путь. Поэтому и приходится вычислять нужную общую длину вручную, и передавать, используя перезагрузку с длиной.

Ответ 2



Для упаковки нескольких файлов предназначен метод CompressFileDictionary - он позволяет полностью контролировать структуру имен в архиве. На вход ему первым аргументом подается Dictionary, с будущим путем в архиве в качестве ключа и настоящим именем архивируемого файла в качестве значения. Если хотите полные имена - просто добавьте полное имя файла одновременно и в ключ и в значение: var archiveName = "C:\\foo\\bar.7z"; var sevenZip = new SevenZipCompressor(); var files = new Dictionary(); foreach (var fileName in Directory.EnumerateFiles("\\\\some-pc\\SomeFiles\\")) { files.Add(fileName, fileName); } foreach (var fileName in Directory.EnumerateFiles("C:\\Another\\Directory")) { files.Add(fileName, fileName); } var fileName = "D:\\And\\Just\\one.file"; files.Add(fileName, fileName); sevenZip.CompressFileDictionary(files, archiveName, "YourPassword"); Если необходимы полные имена unix-подобном стиле - просто отрезайте корневой элемент пути(букву диска либо косую черту в UNC-путях) из внутриархивного названия файла.

java.text.ParseException: Unparseable date

#java


Столкнулся с проблемой, не работает следующий java - код:

String s_date = " Ср, 16 12 2015 16:24:31 GMT";
SimpleDateFormat sdf = new SimpleDateFormat( "     dd MM yyyy hh:mm:ss    " );
Date date = sdf.parse( s_date );
System.out.println( sdf.format( date ) );


Выкидывает:

java.text.ParseException: Unparseable date: " Ср, 16 12 2015 16:24:31 GMT"


Можно конечно обрезать первые пять символов и последние четыре. Но у меня будет много
разных форматов дат, и для каждой разный подход. Как сделать чтобы SimpleDateFormat.parse(),
парсил только то что указано?

Если в коде не видно, я в задании шаблона подставил 5 пробелов в начале и 4 в конце,
это не помогло.
    


Ответы

Ответ 1



Конкретно в вашем случае надо править форматную строку: // было: "dd MM yyyy hh:mm:ss" // модификации: EEE - день недели строкой, HH - час 0-23, zzz - временная зона SimpleDateFormat sdf = new SimpleDateFormat( " EEE, dd MM yyyy HH:mm:ss zzz", new Locale("ru", "RU") ); Date date = sdf.parse( s_date ); System.out.println( sdf.format( date ) ); //Вывод: Ср, 16 12 2015 19:24:31 MSK Новое API: DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern( "E, d M y H:m:s z", new Locale("ru", "RU") ); ZonedDateTime newDate = ZonedDateTime.parse( s_date.trim(), newFormatter ); System.out.println( newFormatter.format( newDate )); // Вывод: Ср, 16 12 2015 16:24:31 GMT

Ответ 2



Возможно, подойдёт использование регулярных выражений, выделяющих нужную часть даты из строки. String s_date = " Ср, 16 12 2015 16:24:31 GMT"; final Pattern pattern = Pattern.compile(".*(\\d{2}\\s\\d{2}\\s\\d{4}\\s\\d{2}:\\d{2}:\\d{2}).*"); final Matcher matcher = pattern.matcher(s_date); if (matcher.find()) { Date date = null; SimpleDateFormat sdf = new SimpleDateFormat("dd MM yyyy hh:mm:ss"); try { date = sdf.parse(matcher.group(1)); } catch (ParseException e) { e.printStackTrace(); } System.out.println(sdf.format(date)); } else { System.out.println("No match!"); } Если же всё совсем плохо и формат даты может быть непредсказуем, то хорошим выбором может стать natty.

Режет форму на разных ОС (Win7/Win10)&Win8.1

#c_sharp #net #winforms #windows_8 #windows_10


Написал небольшое приложение. И на кросс-платформенности споткнулся.
Что имеем:

Win10, разрешение 1366х768



Win10, разрешение 800х600



А теперь Win8.1, разрешение 1920х1080


На Win8 срезает кусок формы, тем самым пропадает кнопка нижняя и боковая, что вообще
неприемлемо, да и textbox-ы подрезает немного. 
Платформа .NET 2.0 (нужна именно она, перекомпилить в .NET 4+ не вариант).
На Win7 c разрешением 1920*1080 все норм!
В чем проблема может быть? 
    


Ответы

Ответ 1



Поиграйтесь с параметрами Anchor и AutoScaleMode Разные контролы по-разному ведут себя с разными значениями этих параметров - проще всего найти правильную комбинацию экспериментально.

Ответ 2



Проблема скорее всего с DPI и абсолютными координатами всех контролов. Насколько помню, Winform не умеет скалить форму под разные DPI, из за чего как раз правый нижний угол и может страдать. В целом, из простых вариантов - явно привязать обрезанные контролы к нижней и правой границе окна, либо дать пользователю растянуть форму, что правда не сильно очевидно будет.

Ответ 3



Решил установкой значения Inherit для свойства AutoScaleModeв формах

Регулярные выражения в форме регистрации

#php #регулярные_выражения


Как учесть только латиницу или кирилицу?

Есть форма регистрации, мне нужно учесть только русские или латинские буквы, но смешивать
их нельзя. Пример: "Lexans" и "Алексей" - разрешено, а "Lexaнс" - нет!

Вот как такое учесть?
    


Ответы

Ответ 1



/^([A-Za-z]+|[А-Яа-я]+)$/u Вот такая регулярка

Кроссплатформенность битовых операций

#cpp #битовые_операции #кроссплатформенность


Как добиться кроссплатформенности при сериализации, работе напрямую с битами, составления
пакетов для отправки между классами при условии, что битовые манипуляции должны быть
верны при little endian и big endian.
    


Ответы

Ответ 1



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

Ответ 2



В полях структур, используемых для обмена, храните данные в сетевом формате (network order, подробнее можете посмотреть здесь). Для преобразования данных между сетевым форматом и форматом хоста можно использовать функции htons()/htonl()/ntohs()/ntohl() из Berkeley sockets API.

Ответ 3



Внутри байта биты всегда идут слева направо от старшего к младшему, независимо от принятого порядка байтов в системе. То же самое касается операндов у операторов >> <<, даже если это числа, состоящие из больше чем 1-го байта. То есть int i=4; i>>=1; i всегда будет равно 2. Для кроссплатформенной (де)сериализации можно использовать htons()/htonl()/ntohs()/ntohl()

Как вставить запись в таблицу MySQL с учетом сортировки по алфавиту?

#php #mysql #sql #сортировка #insert


Есть некая картотека людей:



Суть картотеки состоит в том, чтобы хранить такие вот карточки, в каждой из которых
записаны по три фамилии изначально. Каждая карточка пронумерована. Фамилии в карточках
и картотеке в целом расположены в порядке сортировки по афавиту. 

В MySQL таблица хранящая данную картотеку выглядит так:


id
card_number (номер карточки)
position (позиция фамилии в карточке)
surname (фамилия)


Задача: добавить новую фамилию в картотеку с сохранением позиций фамилией, которые
там уже есть, но в ближайшую по сортировке карточку. 

К примеру, нам нужно добавить фамилию "Иващенко"
Фамилия Иващенко по правилам сортировки должна быть после Иванов и перед Илитаев,
но так как нам нельзя менять порядок уже существующих в карточке фамилий, то мы должны
просто добавить её в конец карточки №1, после фамилии "Илитаев"

В итоге получается мне нужно каким-то образом для заданной фамилии (например для
"Иващенко" №1) определить номер карточки в которую я собираюсь добавить эту фамилию.  
    


Ответы

Ответ 1



select * from card where surname=( select max(surname) from card where surname<'Иващенко' ) Даст ту же запись, которую дал бы приведенный вами PHP алгоритм. Если надо определять некие "расстояния" между фамилиями - что бы найти действительно "ближайшую", то вам и на PHP придется попотеть. Но это в принципе то же решаемо. Например вы можете аналогичным SQL запросом получить запись идущую после вставляемой и уже между ними двумя на php вычислять какая "ближе" Если приведенный запрос не вернул ни одной записи, значит задали фамилию которая должна быть первой в картотеке. Т.е. такую запись надо точно добавлять в первую карточку картотеки.

Как лучше всего рассчитывать прогресс выполнения и задавать его цену?

#c_sharp


Есть некая операция, которое состоит из последовательности действий. 

void MyOperation
{
    Action1();
    Action2();
    Action3();
}


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

void MyOperation
{
    [CostAttribute(30)]
    Action1();
    [CostAttribute(40)]
    Action2();
    [CostAttribute(30)]
    Action3();
}


А в самих функциях должен посчитаться общий прогресс (30 + 40 + 30) и текущий для
действия (общий/текущий). 

То есть если программист добавляет новое действие (Action4), он примерно оценивает,
сколько оно будет выполняться и выставляет свою цену, например 100, не меняя остальные
цены и соотношения.

Как такое можно сделать? 

UPD:

Сначала мне пришло в голову сделать так. Поставить атрибут с ценой над каждым определением
действия. Но действие может иметь разную цену в зависимости от контекста. Например,
действие копирует файлы. В этом случае оно может использоваться в операции несколько
раз, и цена его будет разная. Программист примерно представляет, сколько файлов имеется
для копирования, а потому в одном случае это действие будет стоить 10 (примерно 1000
файлов), а в другом - 20 (примерно 2000 файлов). Короче не знаю как это сделать красивее
и удобнее в понимании и программировании.
    


Ответы

Ответ 1



Как вариант, можно обернуть MyOperation и Action в классы. В этом случае MyOperation хранит набор Action и выполняет их поочередно. После выполнения действия можно пересчитать прогресс выполнения, используя параметр action.Weight (он же цена). public class MyOperation { List actions=new List() public void Run() { foreach(var action in actions) { action.Execute(); this.ResearchProgress(action.weight); } } }

Анимация Transform в ControlTemplate

#wpf #xaml


Как анимировать ScaleTransform кнопки в шаблоне, и какой тип анимации необходимо
применить?
    


Ответы

Ответ 1



Вам нужно анимировать не всю трансформацию, а свойства ScaleX и ScaleY этой трансформации. Так как тип этих свойств double, соответственно, нужно использовать DoubleAnimation.

Передать два значение в Ajax на сервер

#jquery #ajax


Есть Ajax который должен передавать два значения. Сделал только со одним.

$.ajax({
    type: 'POST',
    url: "/ajax/search_bid_country",
    data: "city_from="+city_from,
    success: function(answer) {
        $(".result_article").empty();
        $(".result_article").append(answer);
        $(".result_article").fadeIn();
        $(".load").css({display:"none"});
    }
});


Но вот второй не могу передать пишит ошибку,

data: "city_from="+city_from, "city_whre="+city_where,


Как быть
    


Ответы

Ответ 1



все просто data: "city_from=" + city_from + "&city_whre=" + city_where, теперь должно сработать

Ответ 2



Конечно будет ошибка, запятая в вашем примере означает переход к другому свойству объекта. Вам нужно в свойство data указать сериализованную строку или объект. Об этом четко написанно в документации. В вашем случае просто вместо запятой использовать конкатенацию: data: "city_from=" + city_from + "&city_where=" + city_where, Либо лучше передать объект: data: {city_from: city_from, city_where: city_where}, Но что будет когда параметров станет ещё больше? Будет много ненужной писанины. Используйте лучше функцию сериализации. data: $("form").serialize(),

Режим киоска на Android

#android


Делаю терминал оплаты (в первом приближении), интерфейс реализуется в виде планшета
на Android, убранного в сейфовый ящик, снаружи доступен только экран. 
Одно из требований заказчика, ставящее меня в тупик - портируемость на другие модели
планшетов, т.е. редактировать программу или прошивку никто не будет, а какой версии
андроид установлен заранее не известно (от 4.1 и выше).

Нужно запретить пользователю выходить из приложения и залезать в настройки. Все "шторки"
и софтовые кнопки (если они есть) надо скрыть.

Есть ли какой-нибудь метод реализовать это без привязки к версии андроида?

Если возможно, надо обойтись без root'ования.
    


Ответы

Ответ 1



Всё зависит от конкретной версии Android. Если 5.0 и выше, то там уже есть штатные функции для работы с режимом киоска. Для более ранних версий это сделать сложнее, но всё же реально: Автоматический перезапуск через манифест; Перехват нажатия системных кнопок; Блокировка панели статуса. Это вкратце. Более подробно можно посмотреть в этой статье.