Страницы

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

пятница, 5 апреля 2019 г.

Android верстка отображется только верхний TextView

В layout присутствуют несколько вертикально расположенных TextView но отображается только один,верхний.
Что не так, как исправить?


Ответ

android:layout_height="match_parent"
изменить на
android:layout_height="wrap_content"
или какое-то значение в dp. Первый элемент у Вас растягивается на весь экран и остальные, соответственно, уже сжаты в 0.

Многопоточный доступ к данным

Один поток пишет в структуру, другие потоки читают. Требуется обеспечить транзакционность записи (т.е. чтобы при обновлении двух полей, потоки чтения не могли получить возможность прочитать наполовину обновленные данные). В идеале для чтения иметь метод const Foo& get() const;
В текущей реализации используется подход с мьютексами и хранением отдельных для каждого потока копий в std::map.
void ConfigUpdater::set(const Config& config) { MutexGuard mutexGuard(mutex); this->config = config; }
const Config& ConfigUpdater::get() const { MutexGuard mutexGuard(mutex); return copies.emplace(boost::this_thread::get_id(), config).first->second; }
Возможно есть лучшее решение, подскажите в какую строну копать.


Ответ

Можно воспользоваться std::shared_lock для чтения и std::unique_lock для записи, это позволить избежать копирования. std::shared_timed_mutex доступен в C++14, в C++17 есть std::shared_mutex

Регулярные выражения в nginx

При гуглении регулярных выражений мне попадаются только огромные статьи и толстые книги. А мне надо только понять как работает это:
location ~* ^.+\.\w+$ { root /home/box/web/public; }
Окей. Начал читать книгу, закончил три главы уже, а полного понимая того, что написано выше все еще нет и, судя по всему, если идти таким путем, то не скоро будет.
Не могли бы вы просто в двух словах объяснить символику этого примера.


Ответ

^ - означает, что соответствие будет искаться с начала строки, а не с любого символа. Выражение /box/ будет соответствовать и box-web и home-box-web, а /^box/ только первой строке.
$ - означает привязку к концу строки /index\.php/ будет соответствовать и site.ru/index.php и site.ru/index.php?v=3, выражение /index\.php$/ будет соответствовать только первому варианту.
.+ - любое количество символов. Точка - любой символ, комбинация .+ - один или больше любых символов.
\. - Так как точка специальный символ, то для того, чтобы обозначить точку, ее нужно экранировать слешем.
\w - любой символ, который может составить слово \w+ - любое количество таких символов (один или больше).
Т.е. выражение ^.+\.\w+$ охватывает почти любой URL. Прицел изначально был на выражения вида hello/index.php.
Регулярные выражения - специальный декларативный язык. Выучить его не так просто, как может показаться на первый взгляд. Его декларативная природа не позволяет использовать опыт и знания, приобретенные скажем в императивных языках программирования. Поэтому изучая его следует запастись терпением - это может занять время. Квантификаторы и спец.символы придется выучить наизусть и добиться полного понимания их работы, как операторов ветвления и циклов в императивных языках. В замен вы получаете очень компактный инструмент для манипуляции строк.

Арифметика в bash

Делаю простой калькулятор на bash:
#!/bin/bash
while [ 1 -eq 1 ] do read arg1 op arg2 if [[ "$arg1" -eq "exit" ]] then break fi
flag=0 for ops in + - * / % ** do if [[ "$op" = "$ops" ]] then flag=1 fi done
if [[ $flag = 1 ]] then let "result = $arg1 $op $arg2" echo "$result" else echo "error" fi
done
echo "bye"
Смысл в том, что на вход я подаю 3 значения, аргументы и операция между ними. Например, 12 + 5
Все хорошо работает, кроме операций * и **
В чем может быть дело?


Ответ

for ops in + - * / % **
заключите по крайней мере * и ** в кавычки. а лучше — все аргументы:
for ops in '+' '-' '*' '/' '%' '**'
тогда оболчка не будет пытаться делать какие-либо подстановки.

Подготовка данных для распознавания речи нейронной сетью

Разбираюсь с распознаванием речи с помощью нейронных сетей. Нашел довольно много информации об устройстве самих сетей, а вот с примерами их работы посложнее.
Допустим есть у меня какая-то сеть с N входами и M выходами. И есть звуковой сигнал с каким-то текстом. Как все это заставить работать вместе?
Получили мы, допустим, с помощью преобразования Фурье спектр. Ну можем как-то нарезать звуковой сигнал на какие-то мелкие кусочки. Опять же, как их выбрать длину куска? И что делать дальше? Что подавать на вход сети? И что сеть на выходе обычно дает? Буквы, соответствующие звукам или еще что-либо? (Допустим, стоит задача получить произнесенное предложение в текстовом виде)
Мне интересен сам алгоритм, как все это происходит от произнесения фразы человеком до получения этой фразы в текстовом виде. Информация, которую я находил освещает обычно либо работу нейронной сети, либо преобразование Фурье. Но как все это работает вместе - не очень понятно.


Ответ

Тема слишком обширная для краткого ответа - ваш вопрос - это повод для хорошего исследования. Однако, гипотезы выдвигать никто не запрещает.
Нейронные сети должны принимать на вход вектор признаков фиксированного размера. Значит нужно как-то нормализовать длину входного вектора. В вопросе вы указали, что есть коэффициенты Фурье после преобразования текста. Тексты бывают очень разной длины и чтобы получить одинаковое количество коэффициентов, длительность сигнала тоже должна быть одинаковой. К тому же найти корпус для обучения по текстам будет проблемой - такой корпус будет иметь монструозные размеры и неприемлимо большое время обучения. Вместо текста можно брать отдельные слова - текст можно разделить на слова, ориентируясь на паузы между словами. Следуя этой логике можно спуститься еще ниже и распознавать отдельные слоги или звуки. Вот пример для слова РОВНО

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

Как в TextView установить разный цвет для каждого символа

Есть к примеру текст "10/5" и как в TextView сделать чтоб к примеру число 10 было зеленым цветом, слэш серым, а число 5 красным


Ответ

Можно избежать использования HTML при помощи такого способа:
TextView TV = (TextView)findViewById(R.id.mytextview01); Spannable word = new SpannableString("Your message");
word.setSpan(new ForegroundColorSpan(Color.BLUE), 0, word.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
TV.setText(word); Spannable wordTwo = new SpannableString("Your new message");
wordTwo.setSpan(new ForegroundColorSpan(Color.RED), 0, wordTwo.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); TV.append(wordTwo);

Вывод SUM для UNION запроса

Добрый день. Есть запрос следующего вида:
SELECT COUNT(id) FROM A WHERE id_C = 2
UNION
SELECT COUNT(id) A FROM A WHERE id_C = 3
Запрос урезал максимально, чтобы была ясна суть.
Есть результаты в таком виде:
4 7
Требуется к этому же результату добавить третьей строкой сумму предыдущих двух строк:
4 7 11
Такое возможно не запиливая дополнительного запроса вида:
SELECT COUNT(id) FROM A WHERE id_C IN(2, 3)
?


Ответ

Классически задача решается при помощи WITH ROLLUP. Однако, в MySQL он работает только в рамках одного запроса, в случае же UNION у вас два отдельных запроса. Можно поступить следующим образом
SELECT COUNT(id) FROM A WHERE id_C IN (2,3) GROUP BY id_C WITH ROLLUP

Ограничение количества запросов к странице

Как можно сделать ограничение кол-ва запросов к php странице к примеру к 3 в 1 сек, и как это лучше реализовать?
P.s Сама страница содержит динамические JSON данные


Ответ

А вы не ограничивайте доступ, просто кэшируйте результат сохраняя его в оперативной памяти, например, в memcached со сроком хранения 3 секунды.
addServer('localhost', 11211);
$json = 'error'; if (!($json = $m->get('json'))) { if ($m->getResultCode() == Memcached::RES_NOTFOUND) { // Долго и трудоемко вычисляем JSON $json = '{...}'; // Устанавливаем значение на 3 секунды $m->add('json', $json, 3); } } echo $json;
Как только memcached уничтожит ключ json, скрипт не обнаружит его, снова вычислит по динамическому запросу, положит в memcached и отдаст клиенту. В промежутке между этими событиями json будет извлекаться из memcached очень быстро. Тогда вы сможете отдавать произвольное количество запросов, не подвергая нагрузке хранилища, ответственные за генерацию JSON-а. Более того, при возрастании нагрузки вы сможете увеличивать время хранения ключа, а при ее снижении, наоборот, сокращать.

Enum как хранилище данных

Имеется абстрактный класс Measurments. Все типы Measurments наследуют данный класс - Temperature, Rainfall и т.д. У каждого типа есть значение и единица измерения. Мне подсказали, что для всех типов единицы измерения нужно создать один enum. Подскажите пожалуйста, как должен выглядеть такой enum и как его связать с каждым классом, где единицы измерений (%, м/сек, мм/кв.м, ю/с/з/в и т.д.)?


Ответ

Хранение единиц измерений можно реализовать так:
public enum Unit { TEMP("C"), // Температура WIND("м/сек"), // Скорость ветра PREC("мм"); // Осадки
private String unit;
Unit(String unit) { this.unit = unit; }
public String value() { return unit; } }
Для направления ветра:
public enum WindDirection { NORTH("север"), EAST("восток"), ...;
private String direction;
Units(String direction) { this.direction = direction; }
public String value() { return direction; } }
Использование:
public class Wind extends Measurments { private static final String UNIT = Unit.WIND.value();
private String value; private WindDirection direction;
Wind(String value, WindDirection direction) { this.value = value; this.direction = direction; }
public String toString() { return "Ветер: " + "скорость " + this.value + " " + UNIT + ", " + "направление " + this.direction.value(); } }
Таким образом Unit будет хранилищем для всех единиц измерений.

Как выйти из цикла python

Ищу циклом текущего пользователя компьютера в локальной сети
def scan_Lan(): ip_list = ['192.168.4.'] i = 50 while i <= 240: scan_ip = ip_list[0] + str(i) response = subprocess.Popen(["ping", "-n", "1", "-w", "200", scan_ip]).wait() if(response == 0): try: wql = 'SELECT * FROM Win32_computerSystem' c = wmi.WMI(scan_ip, user='office\admin', password='fff') for item in c.query(wql): currentUser = str(item.UserName) print(currentUser) if(currentUser == "ivanov"): print(scan_ip) break except: print("-") i += 1 print("end")
scan_Lan()
Все хорошо работает, но хочу после поиска выходить полностью из цикла while, как это сделать? Поставил вот здесь
print(scan_ip) break
но он по всей видимости выходит только из for, а как сделать глобальный break?


Ответ

break прекращает только вложенный цикл. Внешний цикл продолжает работать. Используйте return, когда результат найден в вашем случае:
if current_user == 'ivanov': return scan_ip

Как пробрасывает порты торрент? C#

Как можно пробросить порт программно? Чтобы соединить два компьютера напрямую(даже с динамическим ip)? Подскажите, куда копать?


Ответ

Соединение двух компьютеров напрямую состоит из двух фаз (подзадач), которые обычно решаются отдельно.
Фаза 1 - обнаружение (discovery)
Чтобы соединиться - надо знать куда соединяться. Иными словами, нужен ip-адрес. Когда клиент соединяется с сервером, обычно используется доменное имя - но при одноранговом соединении, как правило, доменные имена компьютерам не назначены. И даже если назначены - их тоже нужно как-то узнать.
Для этого есть несколько способов.
Ввод ip-адреса (или доменного имени) пользователем напрямую. Если в вашем случае предполагается, что этот вариант и будет основным - дальше про обнаружение можно и не читать. Сканирование сети. Разумеется, перебирать ip-адреса и порты не следует: есть более простой способ кооперативного обнаружения - широковещательные пакеты. Можно на одной стороне отправить UDP-пакет на широковещательный адрес, а на другой принять его на известный порт. В старых сетевых играх это был основной способ обнаружения, он неплохо показывает себя в пределах одного сегмента локальной сети.
Более современный вариант - отправка пакета на групповой адрес. Гуглить по слову IGMP Использование общего каталога. Нужно создать сервер, который бы занимался распространением знаний клиентов друг о друге. Примеры: в сетевых играх от Blizzard этим занимаются сервера Battle.Net. В сети bittorrent этим занимаются торрент-трекеры. Использование распределенных хранилищ данных. Гуглить по слову DHT
Фаза 2 - соединение
И так, у нас есть ip-адрес другой стороны, и возможно даже посредник, через которого можно связаться и договориться о технических параметрах соединения.
Отмечу особенно, что нам совершенно не важно, статический или динамический этот адрес. Важно лишь, что он назначен нужному компьютеру - и мы его знаем! Осталось установить соединение.
Тут снова есть варианты.
Если один из компьютеров "видит" другой - то он к нему может подключиться напрямую. Отмечу, что имеет смысл пробовать оба варианта, поскольку возможность установления соединения не обязательно симметрична. К примеру, торрент-клиенты умеют работать даже при полностью закрытых для входящих соединений портах - соединяясь с теми, у кого они открыты. Или, другой пример, протокол FTP - в нем соединение для передачи данных может быть открыто как в активном (сервер соединяется с клиентом), так и в пассивном (клиент соединяется с сервером) режимах. Пользователя можно попросить открыть порт вручную. Протокол UPnP позволяет, в том числе, открыть порт на локальном роутере - если он его поддерживает. Если компьютер закрыт NATом - но этот NAT не является симметричным, то можно воспользоваться "багофичей" NAT. Дело в том, что UDP-пакет, отправленный "наружу", открывает случайный порт для приема информации "внутрь". И в некоторых типах NAT этот самый входящий порт доступен не только для того адреса и порта, на которые был отправлен первый пакет. Таким образом, для протокола UDP для некоторых типов NAT можно открыть входящий порт. За это отвечает протокол STUN Некоторые провайдеры или организации до сих пор предоставляют доступ в интернет через прокси-сервер. HTTP(S) или SOCKS4-прокси в этом плане нам бесполезны, но вот SOCKS5-прокси позволяет открывать порт на прием соединений. Если все совсем плохо - может помочь VPN или туннелирование. Обычно такие вопросы оставляют пользователю - но вот Skype, к примеру, своей популярностью обязан в том числе способности туннелировать трафик через т.н. супер-ноды (супер-нодой может (мог?!) внезапно стать любой компьютер с разрешенными входящими подключениями, толстым каналом и запущенным скайпом).

Что означает auto mode в update-alternatives --config java?

Что означает auto mode в update-alternatives --config java? Вот, что нашел в man, но это ситуацию не особо разъяснило.
automatic mode When a link group is in automatic mode, the alternatives system ensures that the links in the group point to the highest priority alternative appropriate for the group. manual mode When a link group is in manual mode, the alternatives system will not make any changes to the system administrator's settings.


Ответ

https://help.ubuntu.com/community/Java
вкратце, это механизм выбора пакетов по приоретам (для апдейтов, допустим). Ну, например, для java cуществуют по крайней мере 4 возможные для установки по дефолту реализации:
OpenJDK Oracle Java IBM Java GNU Compiler
автоматический режим выберет ту реализацию, которая считается системой "самой правильной"
ручной - оставит ту, которую ты указал изначально.
я бы советовал использовать автоматическую, а ручной режим выбирать только если ты точно знаешь, что твой софт не работает, например, с OpenJDK, а только с Oracle Java

пишем на php cli

Добрый вечер.
Часто приходится писать скрипты на php (одноразовые), перенос данных с одного сайта на другой, парсинг и т.д. Выполнения скрипта может занимать 30-100 мин. Естественно запуская скрипт через обычный браузер, обращаясь через http к скрипту, то сервер после некоторого времени (30, 60, 120) сек, возвращает 503, разрывает соединение. Разные настройки сервера не помогают.
Читал, что помогают в таких случаях, писать php скрипты под консоль. Так называемый php cli.
Подскажите пожалуйста, как мне это сделать? Предположим у меня есть хостинг со скриптами, мои дальнейшие действия? Не могу разобраться, где открыть эту консоль и т.д. Насколько я понял, php cli это просто такой режим запуска интерпретатора, с некоторыми параметрами.


Ответ

Допустим, у вас есть компьютер с Windows. Вы можете открыть консоль и набрать там какие-нибудь команды. набрать dir и и получить список каталогов и файлов, скопировать файлы командой copy: copy c:\a.txt d:\b.txt
это консоль Windows. Если на вашем компьютере установлен php, вы можете открыть консоль, набрать что-нибудь вроде c:\lamp\php\bin\php -i и увидеть настройки php.
Теперь представьте себе ваш хостинг. Операционная система, но не Windows, а Linux. Скорее всего у него нет графической оболочки. Единственный ваш способ общения с ним - через командную строку.
PHP CLI расшифровывается именно так: Command Line Interface. Интерфейс командной строки.
Если у вас есть ssh-доступ к вашему сайту, вы сможете им воспользоваться чтобы запускать php-скрипты в консоли, творить прочую консольную магию.
Заходите через ssh на ваш хост (ssh example_user@example.org), попадаете в консоль и запускаете php ваш_скрипт.php
главные отличия между php-cli и "php через браузер":
1) php-cli выполняется с правами пользователя, который его запускает, php-через-браузер выполняется с правами "пользователя" веб-сервера.
2) Вы можете запустить что-нибудь в духе sudo php someFile.php и выполнить его с правами рута (самого главного пользователя в системе)
3) В php-cli по умолчанию нет ограничения по времени выполнения скрипта.
Если вы, допустим, подзабыли, как в принципе работает php - напомню. вашему серверу (apache, nginx) прилетает запрос - допустим на index.php - сервер посылает этот запрос демону php-fpm, который исполняет файл index.php, а результаты отправляет серверу, а сервер - вашему браузеру.
Это как если бы вам приходило письмо от друга с просьбой зайти в консоль, выполнить какой-то php-скрипт и прислать результат выполнения обратно.
Только гораздо быстрее.
В принципе, так интерпретаторы языков программирования и работают, на самом деле - через консоль. Поддержка веб-сервера полностью факультативна.
Детали и настройки вы можете найти в мануале PHP.

Правильный подход к организации хранения routes в Symfony

Здравствуйте!
В данный момент я изучаю Symfony 2 и предо мной встала такая дилема:
Как лучше хранить routes для контроллеров?
Да, я понимаю что этот вопрос с немного холиварным подтекстом, ибо на вкус и цвет... Но все же меня интересует этот вопрос с точки зрения огранизации средних/больших приложений.
Приведу свои размышления:
Насколько мне известно, Symfony имеет 2 основных варианта хранения routes
В конфигах (routing.yml, routing.xml и тд), возможно также подключать routing из бандлов. В аннотациях
Наиболее удобным мне кажется вариант с аннотациями, но когда контроллеров и методов станет много, скажем 50+, возникнет сложность определения что и где находится, и как следствие усложнение разработки и дебага.
Также приемлемым мне кажется складывать routes в routing файлы каждого бандла. В этом случае будет удобно повторно использовать бандлы в других проектах, и зная за какой функционал отвечает определенный бандл, искать нужные роуты. Но все же при большом количестве бандлов это может стать проблемой.
Третий вариант - это хранить все роуты в app/config/routing.yml. Но это усложнит повторное использование бандлов. И, почему-то, мне этот вариант интуитивно не нравится.
Со стороны может показаться что я задал вопрос и сам же на него ответил. Это не так. Я вижу эти варианты, но не знаю какой и когда лучше использовать, так как нет опыта сколько-нибудь серьезной разработки на Symfony.
Буду рад и благодарен любому мнений, и в двойне - мнению аргументированному.


Ответ

Использую Symfony два года, на 4 проектах. В первых двух использовал конфигурирование маршрутов в yaml-файле, на третьем решил попробовать аннотации. Понял, что использование аннотаций гораздо удобнее, хотя поначалу думал "как хорошо когда все маршруты в одном файле". Совсем наоборот. Как минимум, при создании нового контроллера приходится что-то делать в двух файлах, а с аннотациями - ctrl+c - ctrl+v в одном файле, чуть переименовал и готово. Если строго следовать именованию файлов и маршрутов - никаких проблем с нахождением нужного контроллера не возникает. Тем более в IDE, где просто по имени роута в шаблоне тыкнул и ты уже в контроллере.
С точки зрения производительности: на первом проекте активно курил доки и рекомендации с аналогичным вашему вопросом. Вычитал где-то, что yaml-файлы производительнее. Но на деле никакой заметной разницы нет, все в любом случае хорошо кешируется и готово к употреблению движком "в лучшем виде".
Добавлю еще, что проекты достаточно крупные, чтобы различия в использовании подходов были заметны. Так вот с yaml-файлом неприятнее: огромная портянка на 1.5к строк, в которой и нужное и ненужное и хочется еще соблюдать какой-то порядок и разделять комментами на разделы, чтобы приличнее было... А с аннотациями все на своем месте, всегда под рукой, никакой каши.

Как узнать версию Python в Linux Ubuntu?

Как посмотреть версию Python в терминале Linux?


Ответ

Версия интерпретатора Python выводится в терминале командой
python --version
Однако, надо иметь в виду, что в современных дистрибутивах Ubuntu (и не только) присутствуют сразу две версии интерпретатора - Python 2 и Python 3. Указанная выше команда вызовет Python 2. Чтобы вызвать Python 3, команда должна быть другой:
python3 --version

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

у меня есть картинка.Мне нужно сделать анимацию по которой галочка покадрово появится
Как это можно сделать?


Ответ

body { font-family: sans-serif; font-size: .9em; } .example-1 { position: relative; width: 50px; height: 50px; box-sizing: border-box; border: 5px solid #ddaa55; border-radius: 50%; } .example-1:after { content: ''; position: absolute; left: 0; top: -10px; width: 0; height: 50px; background: url(http://iconspot.ru/files/175351.png) 0 0 no-repeat; background-size: cover; transition: width .5s; } .example-1:hover:after { width: 50px; } .example-2 { position: relative; width: 50px; height: 50px; box-sizing: border-box; border: 5px solid #ddaa55; border-radius: 50%; } .example-2:after { content: ''; position: absolute; left: 0; top: -10px; width: 50px; height: 50px; background: url(http://iconspot.ru/files/175351.png) 0 0 no-repeat; background-size: cover; animation: .5s linear 0s infinite alternate check; } @keyframes check { from { width: 0; } to: { width: 50px; } }

При помощи transition. Можно использовать при смене состояния и с добавлением класса (наведите курсор):

При помощи animation. Можно использовать как при смене состояния или с добавлением класса, так и без какого-либо события:


Свойство transition
Использование CSS анимации

Что означает final когда указано как модификатор к параметру?

Я уже не раз встречал, но только вот подумал... А что означает такая конструкция, когда допустим в методе один из параметров имеет модификатор доступа final...
Ведь в любом случае при повторном вызове метода ему можно передать новое значение...


Ответ

Если указан параметр final когда объявляется переменная, то его нельзя будет изменить.
public void i1(final String i1) { i1 = ""; // ошибка компиляции } Также параметр final даёт к себе доступ анонимным классам. Знаю такой пример на Android при запуске Activity
@Override protected void onCreate(final Bundle i1) { super.onCreate(i1); setContentView(R.layout.layout_i1); new AlertDialog.Builder(this) .setTitle(getString(R.string.app_name)) .setPositiveButton("ОК", new DialogInterface.OnClickListener() {
@Override public void onClick(DialogInterface i2, int i3) { i1.clone(); // вот тут можем его получить Только потому, что у Bundle i1 указан параметр final return; }
}) .setNegativeButton("Выход", new DialogInterface.OnClickListener() {
@Override public void onClick(DialogInterface i1, int i2) { i1.cancel(); finish(); return; }
}) .create() .show(); }
Ведь если заменить эту строку
protected void onCreate(final Bundle i1) {
на это
protected void onCreate(Bundle i1) {
то вот здесь
@Override public void onClick(DialogInterface i2, int i3) { i1.clone(); <<<--------- в этой строке return; }
будет ошибка компиляции.

Как писать простенькие приложения для Android, используя яп Python? [закрыт]

Тратить огромное кол-во времени на изучение java, для написания простеньких бот-программ считаю не лучшим решением


Ответ

Python-for-android Прежде всего давайте посмотрим на то, с помощью чего Python получает возможность работать под Android — инструмент, названный, как ни странно, python-for-android. Его основная функция состоит в том, чтобы создать дистрибутив — папку проекта, содержащую все необходимое для запуска вашего приложения. А точнее, сам интерпретатор, Kivy и библиотеки, от которых он зависит: Pygame, SDL и несколько других. Также дистрибутив включает в себя загрузчик Java, отображающий OpenGL и выступающий в качестве посредника между Kivy и операционной системой. Затем вы добавляете ко всему этому свои скрипты, настройки вроде иконки и имени, компилируете с помощью Android NDK и вуаля — APK с вашим приложением готов!
И это всего лишь базовая процедура, на самом деле сгенерированный пакетный файл может включать (и включает) в себя гораздо больше. Вместе со всем прочим в APK вшивается большая часть стандартной библиотеки, а любой сторонний модуль, написанный на Python, может быть легко добавлен — все так же, как и при разработке десктоп-приложений. Добавка модулей с компилируемыми компонентами тоже не вызывает трудностей, необходимо лишь указать, как их нужно собирать. Как правило, это не представляет собой ничего сложного, достаточно лишь поставить пару галочек перед запуском процедуры сборки, хотя в редких отдельных случаях могут понадобиться дополнительные действия. Python-for-android уже включает в себя указания для компиляции таких популярных модулей, как: numpy, sqlite3, twisted и даже django!
Вышеописанные принципы лишь в общих словах объясняют, как работает python-for-android. В любой момент вы можете получить больше информации на данную тему, заглянув в документацию Kivy. Я рекомендую вам Buildozer — надстройку для python-for-android, предоставляющую собой удобный интерфейс и автоматическое разрешение некоторых зависимостей. Мы стараемся сделать так, чтобы написанная выше цепочка действий использовалась не только в Kivy, но и в других проектах. Основной процесс сборки останется таким же, но нужда в загрузчике Java отпадет, так как он необходим только для поддержки некоторых специфичных нужд фреймворка.
Обращение к Android API с помощью PyJNIus Взаимодействие с Android API: получение информации с сенсоров, создание уведомлений, вибрация, пауза и перезапуск, да что угодно — важная часть вашего приложения. Kivy за вас позаботится об основном, но многими вещами вы захотите управлять сами. Для этого создан PyJNIus — инструмент, автоматически оборачивающий код на Java в интерфейс Python.
В качестве простого примера приведем программу, которая заставит телефон вибрировать на протяжении 10 секунд:
from jnius import autoclass # Для начала нам нужна ссылка на Java Activity, в которой # запущено приложение, она хранится в загрузчике Kivy PythonActivity PythonActivity = autoclass('org.renpy.android.PythonActivity') activity = PythonActivity.mActivity Context = autoclass('android.content.Context') vibrator = activity.getSystemService(Context.VIBRATOR_SERVICE) vibrator.vibrate(10000) # аргумент указывается в миллисекундах
Если вы знакомы с Android API, то без труда заметите, что код выше очень похож на аналогичный на Java — PyJNIus просто позволяет нам обращаться к тому же API, но прямо из Python. Большая часть Android API может быть вызвана подобным образом, что позволяет достичь того же функционала, что и при разработке на Java.
Главный минус PyJNIus в том, что он требует неплохого понимания структуры Android API, а код выходит громоздким, хотя его эквивалент на Java выглядит точно так же. Для решения этой проблемы Kivy включает в себя Plyer.
Plyer: кроссплатформенное API для платформоспецифичных задач Проект Plyer ставит себе цель создать простой «питоничный» интерфейс для функций, которые присутствуют на большинстве платформ. Например, код выше легким движением руки превращается в…
from plyer.vibrator import vibrate vibrate(10) # В Plyer аргументы указываются в секундах
Более того, написанный код попытается выполнить свою задачу на всех поддерживаемых Plyer платформах — на данный момент это: Android, iOS, Linux, Windows и OS X (для iOS также существует аналог PyJNIus, называемая PyOBJus). На самом деле, вибрация — не самый лучший пример, потому что сейчас она реализована только для Android, но такие функции как проверка уровня заряда батареи:
from plyer import battery; print(battery.status)
или text-to-speech:
from plyer import tts; tts.speak('hello world')
— работают как в десктопных, так и в мобильных приложениях, а получение данных с компаса/гироскопа и отправка SMS без проблем реализуются на Android и iOS.
Plyer находится на начальной стадии развития, так что любая помощь в разработке приветствуется. Также, мы участвуем с ним в Google Summer of Code в этом году.
Не только ради Kivy Все вышеперечисленные инструменты были разработаны для нашего фреймворка, но на самом деле они больше предназначены для разработки под Python в целом. В Plyer мы специально избегаем какой-либо зависимости от Kivy, а PyJNIus нужен лишь для доступа к Android JNI. Искренне надеемся, что эти инструменты станут полезны для любого, кто пишет на Python под Android. Вы уже можете попробовать PyJNIus, используя QPython. Python-for-android больше завязан на взаимодействии с Kivy, но мы будем рады обсудить этот вопрос.
Многое можно реализовать при разработке на Android с помощью Python, несмотря на все различия с Java, которая предназначена для этого, но эти возможности могут быть расширены еще больше в ближайшем будущем. И если вы заинтересовались описанными выше проектами, то самое время присоединиться к нашей команде!
Оригинальная статья "Kivy Planet" Русский источник "Как разрабатывать на Python под Android"

Переход на другое Activity через 5 секунд

Здравствуйте. Хочу в приложении сделать что-то вроде заставки. Пользователь заходит в приложение, ему открывается первая Activity, и через 5 секунд бросает на другое.
Делаю так:
int ii = 0;
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.fon);
try {
TimeUnit.SECONDS.sleep(5); ii = 5;
} catch (InterruptedException e) { // TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(ii);
if (ii == 5) { Intent intent2 = new Intent(this, Web.class); startActivity(intent2); }
}
И получается в результате следующее: Пользователь заходит в приложение, ему видно первое Activity и через 5 секунд открывается другое активити. Но проблема в том что на первом активити ему не видно экрана, то есть не работает setContentView(R.layout.fon);
Что я делаю не так? Буду благодарен за помощь!


Ответ

Вы приостановили главный поток строкой
TimeUnit.SECONDS.sleep(5);
Так у вас вообще должно было вылететь по ANR
Останавливать главный поток не надо. Это плохая практика. Вам надо сделать иначе - запустить отложенную задачу один из множества способов, например, так:
Thread thread = new Thread() { @Override public void run() { try { TimeUnit.SECONDS.sleep(5); Intent intent2 = new Intent(ТУТ_ИМЯ_КЛАССА_АКТИВИТИ.this, Web.class); startActivity(intent2); } catch (InterruptedException e) { e.printStackTrace(); } } };
thread.start();

Найти все элементы массива, между двумя заданными значениями

Код я не буду сбрасывать, так как его нет, есть только та часть, которая не поможет понять саму суть программы, но попробую объяснить на примере.
Допустим, у меня есть последовательность точек {112, 1, 30, 69, 3, 29, 74, 23, 12} и моей начальной точкой является 30, в то время как конечной является точка 23. Что мне нужно сделать, чтобы я рассматривал лишь точки {30, 69, 3, 29, 74, 23} и вывел на экран, что именно эти точки находятся между начальной и конечной точками.
Код внизу, это как мысль, которая была у меня, но я не могу докончить, так как если я начинаю с 30, как дальше сделать так, чтобы она взяла именно 69. Дистанцию не могу использовать, так как дистанция между 1 и 30 меньше чем дистанция между 30 и 69. Но я верю, что есть какая-то логика или как-то это возможно построить. Возможно моя начальная логика построена неправильно, я буду рад изменениям.
while(current!=end) { for(points= theVectorOfPoint.begin();points!=theVectorOfPointe.end();points++) {
} }


Ответ

Вот мой вариант.
/* Отвечает за номер точки */ current = 0;
/* Note: Для 30 можно отдельную переменную завести и для 23 */ /* В цикле находим номер точки, равной 30 */ while (points[current] != 30) { current++; }
/* И выводим все точки с 30 по 23, найдя которую выходим из цикла */ while (current < end) { cout << points[current] << " ";
if (points[current] == 23) { break; }
current++; }

Как закрыть поиск в toolbar

Пишу простенький мессенжер. Имею такую форму с диалогами:
После того как я ввожу в поиске имя нового собеседника и выбираю его, то меня перебрасывает на новую activity мне можно переписываться. Проблема в том что когда я возвращаюсь в activity с диалогами, на ней до сих пор остаёмся поисковая фраза с логином, собеседника, которого мы искали до этого. То есть так:
Так вот вопрос такой: как мне закрывать/убивать эту строку поиска при возвращении на activity с диалогами?
//********* Имею такую разметку:


Ответ

private SearchView searchView;
@Override public boolean onCreateOptionsMenu(Menu menu) { ... MenuItem searchMenuItem = menu.findItem(R.id.action_search); searchView = (SearchView) searchMenuItem.getActionView(); ... }
@Override public void onResume() { super.onResume();
searchView.setQuery("", false); searchView.clearFocus(); searchView.setIconified(true); // Если надо не только очистить, но и свернуть }

Обьясните в чем разница между symbol и string

На примере 2-х хешей hash={:fruit=>"Apple", :vegetable="Cucumber"} и hash={"fruit"=>"Apple", "vegetable"="Cucumber"}. Расскажите в чем разница между этими сущностями и где применяют symbol.


Ответ

Переменная - это именованная область памяти, она содержит имя и значение, значение можно менять.
Строка - это просто область памяти, которую вы можете изменять.
Символ - это просто имя. Эта конструкция очень популярна в функциональных языках и обычно называется атомом - нечто неделимое и неизменное. Например, белый цвет, :white - нет надобности для значения, нет надобности для изменения - белый цвет останется белым цветом, чтобы не происходило. Это символ в Ruby.
Используется символы там, где значение не требуется, например, для перечислений, передачи имени ключа или метода. Строки и символы можно преобразовывать друг в друга, однако это разные классы.

Межпроцессное взаимодействие, nodejs + nodejs, nodejs + qt и не только

Есть необходимость реализовать двухсторонний обмен данными между разными частями системы. На данный момент в системе присутствуют:
модуль взаимодействия с внешними пользователями через rest api, реализован на nodejs; модуль в котором реализована бизнес логика и взаимодействие с БД, реализован на qt;
Планируется:
веб морда для удобства взаимодействия с системой физических пользователей, будет написана на reactjs.
Сейчас между nodejs и qt данные гоняют по веб сокетам. По ним же планируем обмен данными и с веб мордой. Еще есть необходимость плагины из которых состоит qt модуль разнести по разным процессам.
Если обмен данными по веб сокетам с фронтендом смущений не вызывает то их использование для организации обмена между qt процессами, а также между ними и nodejs смущает. Есть ли более подходящие технологии для этого с учетом того что qt плагины и nodejs приложения находятся на одном сервере.


Ответ

Есть масса методов взаимодействия между процессами. К примеру, его можно организовать с помощью простого TCP сокета. Для этого есть поддержка в node.js из коробоки. В Qt для этого используется QTcpSocket. Это самый простой вариант, потому что и там и там есть поддержка из коробки и на выходе мы имеем асинхронный IPC.
Другим вариантом может быть использование разделяемой памяти. Судя по всему, есть горстка дополнений для node.js добавляющих поддержку оной. В Qt есть готовый класс QSharedMemory. Этот метод хуже, т.к. требует дополнительных плагинов и он синхронен(нужно «опрашивать» разделяемую память).
Идём дальше: D-Bus. В node.js есть дополнение для этого, в Qt тоже есть: Qt D-Bus
Безусловно, можно ещё придумать способов. Что из вышеприведённых лучше? Я считаю, что самым простым и удобным будет использование обычного TCP сокета.

Как перевести текст из 1251 в utf-8

Есть текст
Заказ звонка технической поддержки
Артемий декодер говорит что это cp1251 Я пробую его перевести в utf-8 однако на выходе еще хуже крякозябры.
private string Win1251ToUTF8(string source) {
Encoding utf8 = Encoding.GetEncoding("utf-8"); Encoding win1251 = Encoding.GetEncoding("windows-1251");
byte[] utf8Bytes = win1251.GetBytes(source); byte[] win1251Bytes = Encoding.Convert(win1251, utf8, utf8Bytes); source = win1251.GetString(win1251Bytes); return source;
}
текст считывается из ini-файла. Через notepad++ просмотрел - все норм с кодировкой. Отсюда следует что проблема в следующем классе для чтения ini-файлов.
class IniFile // revision 11 { string Path; string EXE = Assembly.GetExecutingAssembly().GetName().Name;
[DllImport("kernel32", CharSet = CharSet.Unicode)] static extern long WritePrivateProfileString(string Section, string Key, string Value, string FilePath);
[DllImport("kernel32", CharSet = CharSet.Unicode)] static extern int GetPrivateProfileString(string Section, string Key, string Default, StringBuilder RetVal, int Size, string FilePath);
public IniFile(string IniPath = null) { Path = new FileInfo(IniPath ?? EXE + ".ini").FullName.ToString(); }
public string Read(string Key, string Section = null) { var RetVal = new StringBuilder(255); GetPrivateProfileString(Section ?? EXE, Key, "", RetVal, 255, Path);
return RetVal.ToString(); }
public void Write(string Key, string Value, string Section = null) { WritePrivateProfileString(Section ?? EXE, Key, Value, Path); }
public void DeleteKey(string Key, string Section = null) { Write(Key, null, Section ?? EXE); }
public void DeleteSection(string Section = null) { Write(null, null, Section ?? EXE); }
public bool KeyExists(string Key, string Section = null) { return Read(Key, Section).Length > 0; }
}


Ответ

string text = "Заказ звонка технической поддержки";
Encoding utf8 = Encoding.GetEncoding("UTF-8"); Encoding win1251 = Encoding.GetEncoding("Windows-1251");
byte[] utf8Bytes = win1251.GetBytes(text); byte[] win1251Bytes = Encoding.Convert(utf8, win1251, utf8Bytes);
Console.WriteLine(win1251.GetString(win1251Bytes));
Output:
Заказ звонка технической поддержки

Написать функцию ToString, которая список своих разнотипных аргументов преобразует в строковой значение (std::string)

Написать функцию ToString, которая список своих разнотипных аргументов преобразует в строковой значение (типа std::string). Длина списка произвольная. Например, для int n = 17; double x = 6.75; ToString(“;”, 25, 3.7, n, x) ;
где “;” – разделитель между элементами, получим строковое значение “25;3.7;17;6.75”;
Есть такое решение, но оно почему-то не может работать больше чем с одной переменной типа double.
#include #include #include #include #include using namespace std; std::string a, c; std::string x_first, c_v, mn; int i = 0,u; char* ch, *ch1, *ch2; template std::string x_f(T&&t) { i++; if (typeid(t) == typeid(char)) { x_first += t; } else x_first += to_string(t); return x_first; } template std::string ToString(T&& t) {
/*if (typeid(t) == typeid(char)) { char x[] = { t }; a += x; } else */ a = to_string(t); /*a.clear();*/
return a; } template std::string ToString(T&& t, Args&&... args) { a.clear(); if (i == 0) c_v = x_f(t); std::string b = (string)ToString(std::forward(args)...); if (typeid(t) == typeid(char)) { c = t; } else c = to_string(t); ch1 = (char*)c.c_str(); ch = (char *)b.c_str(); ch2 = (char*)c_v.c_str(); strcat(ch1, ch2); strcat(ch1, ch); //strcat(ch1, to_string(t).c_str()); mn = ch1; return mn; }; int main() { string my_x = ToString(';', 4.5,6.9, 8.4); auto h = [=](string x, string y) { return x.erase(0, 2 *
strlen(y.c_str())); }; cout << h(my_x, x_first);
return 0; }


Ответ

В C++17 это можно будет сделать при помощи fold expression (выражения свертки):
template std::string ToString(const T&... t) { std::stringstream ss; (ss << ... << t); return ss.str(); }
В C++11 это делается через разворачивание пака в инициализаторе временного массива:
template std::string ToString(const T&... t) { std::stringstream ss;
int temp[] = {((ss << t), 0)...}; (void)temp;
return ss.str(); }
В выражении (ss << t), 0 используется оператор запятая, левая часть это сайд-эффект (запись в поток), правая часть - инициализатор элемента массива.
Вместо массива можно использовать список инициализации:
(void)std::initializer_list{((ss << t), 0)...};

Мультизадачность на Python: выполнить две долгие функции одновременно, не блокируя GUI

Всем доброго времени суток. Изучаю возможности графического модуля tkinter на Python. Возникла необходимость одновременного запуска нескольких функций, т.е. имеется, например, две кнопки, каждая со своим функционалом. Нужно сделать так, чтобы окно с кнопками после нажатия на одну из них не зависало и позволяло нажать другую кнопку, незамедлительно запустив ее функцию. Пишу на питоне версии 3.5.2.
from tkinter import *
def whilefunc1(): n = 1 while (n <= 100000): print(n) n = n + 1
def whilefunc2(): n = 100001 while (n <= 200000): print(n) n = n + 1
root = Tk() root.geometry("200x200")
but1 = Button(root, text="press me", command = whilefunc1) but1.pack() but2 = Button(root, text="me 2!!", command = whilefunc2) but2.pack()
root.mainloop()


Ответ

Общая особенность GUI программирования в том, что не следует использовать блокирующие функции в обработчиках событий, которые выполняются как правило в GUI потоке, иначе это приводит к "подвисанию" GUI.
В вашем случае вместо self.status[ip] = os.system(f'ping {ip}') можно использовать self.process[ip] = subprocess.Popen(['ping', ip]) и позже проверять статус используя self.process[ip].poll() (оба вызова возвращаются сразу, не дожидаясь пока команда завершится). Периодический опрос можно организовать используя root.after(), например как в start_process(). Можно избежать опроса, если настроить обработчик сигнала, который вызывается когда запущенный дочерний процесс завершается, например, на Unix (усложнённая опция в данном случае). Cross-platform пример кода это QProcess.finished сигнал из Qt GUI библиотеки, который позволяет подключить свой обработчик, который вызывается, когда команда, запущенная QProcess::start, завершается (finished сигнал реализован эффективно, используя функциональность, предоставляемую соответствующей операционной системой, не требуя периодического опроса статуса запущенного дочернего процесса).
Альтернативно, если необходимо запустить числодробительную задачу (CPU-bound), то для этого можно создать пул процессов:
from concurrent.futures import ProcessPoolExecutor
pool = ProcessPoolExecutor()
и использовать command=lambda: pool.submit(whilefunc1) в качестве обработчика событий для кнопки (.submit() ставит выполнение whilefunc1() функции в очередь и сразу же возвращается). Если вы нажмёте 1000 раз на кнопку, то вы скорее всего не хотите запускать 1000 процессов (системе вероятно плохо будет). ProcessPoolExecutor() по умолчанию использует все доступные CPU ядра, не запуская излишние процессы. В этом смысле, это решение более предпочтительно чем решения, использующие threading.Thread(..).start() или multiprocessing.Process(..).start(), где каждое нажатие на кнопку приводит к запуску нового потока/процесса.
Если задача связана с вводом-выводом, то можно использовать Widget.tk.createfilehandler() или аналогичную функциональность в других GUI библиотеках (например, GObject.io_add_watch()). Вот пример кода, где root.createfilehandler() используется чтобы читать вывод внешней команды, не дожидаясь её завершения.
Поддержка createfilehandler() может быть ограничена на некоторых платформах (Windows), поэтому ту же задачу можно переносимо выполнить используя фоновый поток (попытка использовать socketpair, чтобы получить переносимый код, оказалась неуспешной: Popen() не принимает соответствующий fileno() на Windows).

Объяснение по fatal error: unexpectedly found nil while unwrapping an Optional value

На сегодняшний день у нас есть 6 практически одинаковых вопросов по сабжу. Давайте один раз напишем полный ответ по этому вопросу и будем в будущем на него ссылаться. Пока публикую под своим именем, если будут добавления/редактирования переставим на сообщество.


Ответ

Давайте один последний раз пройдемся по unexpectedly found nil while unwrapping an Optional value и больше никогда к нему не будем возвращаться.
Когда вы создаете переменные инстанса, swift от вас хочет, чтобы вы либо сразу им присвоили значения по дефолту, либо инициализировали их в init. Во многих случаях это нам не подходит, тогда мы объявляем свои переменные как optional.
var test:Int? // вопрос в конце, это объявление опциональной переменной
Что значит Optional? Это значит, что вместо просто переменной, например Int, мы получаем инумерацию из двух значений: none и some(Wrapped). Вот это Wrapped и есть значение нашей переменной.
Соответственно, если переменная не присвоена, то при попытке к ней обратиться, получим none т.е. nil.
Если же она содержит значение мы получим Optional(value)
Вот пример:
var test:Int? print(test) // напечатает 'nil' test = 42 print(test) // напечатает 'Optional(42)'
Далее, чтобы избавиться от этого Optional нам надо ее развернуть (unwrap), то есть сказать, что мы точно уверены, что там что то есть и мы хотим получить это самое что то. Другими словами, вместо Optional(value), получить value. Чтобы сделать принудительное разворачивание (forced unwrap) мы добавляем '!'. При этом, если переменная не присвоена, мы получим крэш - тот самый unexpectedly found nil while unwrapping an Optional value.
Пример:
var test:Int? print(test!) // крэш unexpectedly found nil и т.д.
var test2:Int? test2 = 42 print(test2!) // напечатает 42
Дальше, если мы хотим создать переменную как Optional, но точно знаем, что в нее будет что-то присвоено до того, как мы ее будем читать первый раз, мы можем ее объявить как Implicitly Unwrapped Optional Type, посредством добавления '!' в объявлении. В этом случае, она опять же будет Optional, но система будет ее принудительно разворачивать (force unwrap) при любом обращении к ней.
var test:Int! // '!' в конце, это обявление implicitly unwrapped optional print(test) // крэш unexpectedly found nil...
var test2:Int! test2 = 42 print(test2) // напечатает 42
А что делать, если мы понятия не имеем есть там что то в этой optional или нет?
var test:Int? if(test != nil) { print(test!) // развернутое значение } else { print(test) // nil }
Либо другой способ, который создает временную переменную с развернутым значением
var test:Int? if let unwrappedTest = test { print(unwrappedTest) } else { print("no value") }
Ну и если вам надо force unwrapped превратить обратно в Optional:
var test:Int! print(test as Optional) // напечатает nil
Optional chaining:
Есть еще такая ситуация, когда надо сделать цепочку вызовов, при этом где то в цепочке может содержаться опциональная перменная.
Вот такой пример дает apple:
Допустим есть класс Residence, и в нем есть переменная numberOfRooms; и есть класс Person, который имеет опциональную переменную типа Residence. Другими словами у человека может быть жилье, с каким то количеством комнат, а может и не быть жилья. То есть при попытке обратиться к человек-жилье-комнаты, мы можем наткнуться на nil вместо жилья.
class Person { var residence: Residence? }
class Residence { var numberOfRooms = 1 }
Теперь мы хотим создать новый Person, и узнать сколько комнат в его жилище (при этом residence может быть nil поскольку он Optional). Для этого мы говорим системе, что мы хотим делать с опциональным значением - либо оставлять его опциональным ('?') со всеми вытекающими последствиями, в частности получить nil вместо количества комнат; либо принудительно его разворачивать, при этом имея риск получить fatal error.
let john = Person() print(john.residence!.numberOfRooms) // крэш unexpectedly ... print(john.residence?.numberOfRooms) // напечатает nil
let tom = Person() tom.residence = Residence() print(tom.residence!.numberOfRooms) // напечатает 1 print(tom.residence?.numberOfRooms) // напечатает Optional(1)
Тут надо заметить, что хотя numberOfRooms не является опциональной, она в этой цепи становится таковой, поскольку цепь идет через опциональную residence?

Возможно ли вычислить реальный IP?

Интересует возможность вычислить реальный IP пользователя (когда тот использует прокси IPv6) если у него отключено почти всё (Flash, Java...). Всё кроме JS


Ответ

Если прокси по настоящему анонимный и человек использует правильное ПО, вы попадаете в настоящий бесперспективняк в решении данной проблемы, хотя не анонимные прокси могут прокидывать при запросе различные заголовки типа X-Forwarded-For где содержиться реальный IP.
Давайте рассмотрим причины, почему ваши попытки бесперспективны при настоящем анонимном Proxy сервере и правильно настроенном ПО:
JS - клиентский язык, не имеет доступа к оборудованию, если его не предоставляет сам браузер через технологии и плагины. Прокси-сервер может хранить всю информацию о подключении, но вы ее не получите без разрешения владельца. Есть возможность использовать не просто прокси, а цепочку прокси-серверов расположенных в разных странах, тогда процесс обращения к одному владельцу прокси уже не пройдет.
Конечным IP всегда является тот, с которого произведен запрос, в данном случае это прокси сервер.
Получается что реальный IP узнать нельзя, но его можно узнать через различные уязвимости в ПО или программном обеспечении которое хотело сделать этот мир лучше используя весь потенциал технологий, так вот к такому относиться webRTC..Часто пользователи о ней даже не знают и не подозревают что она включена.
Есть возможность утащить реальный IP и даже локальный IP через утечку адреса в технологии webRTC (webRTC ip leak), если пользователь не отключил у себя ее в браузере или имеет клиентское ПО поддерживающее данный протокол.
Технология WebRTC была создана разработчиками Google для быстрой передачи и защиты конфиденциальной информации с использованием браузера, не устанавливая никаких дополнительных программ и расширений.
Демонстрация работы утечки скрытого IP продемонстрирована на проекте в Github

Зачем передавать Looper в Handler?

В офф документации очень коротко описано о том, что такое Looper
Можете объяснить что это и зачем его передавать в Handler
Как в этом примере
new Handler(mBackgroundThread.getLooper());
Или вот еще один пример, в чем разница выполнения этих Hendler
new Handler().post(new Runnable() { @Override public void run() { //Execute some task } });
new Handler(getContext().getMainLooper()).post(new Runnable() { @Override public void run() { //Execute some task } });
При чем информации и примеров использования Looper как параметра очень мало и не понятно, толи из-за того, что это очень редко используется толи из-за того, что мало кто понимает как этим пользоваться...
Реализация Handler в Thread
class LooperThread extends Thread { public Handler mHandler;
public void run() { Looper.prepare();
mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } };
Looper.loop(); } }


Ответ

Looper - это что-то вроде фонового потока, который работает постоянно, не завершаясь. Чтобы передать в этот фоновый поток выполнение какой-либо операции, используется Handler
Если создавать Handler, не передавая в него Looper, то Looper возьмется из того потока, в котором вызывается конструктор Handler(), при условии, что этот родительский поток является HandlerThread.
Поток UI в Android является как раз таким потоком-лупером. Используя Handler, можно передавать в UI поток выполнение определенных операций вызовом метода post(Runnable). Естественно, не стоит надеяться, что тело метода run() выполнется в момент вызова метода post
В Вашем примере mBackgroundThread является наследником HandlerThread, следовательно имеет Looper
Разницы во втором Вашем блоке кода никакой нет, если оба конструктора Handler() вызываются из UI - потока.

Почему margin не накладываются друг на друга и как это исправить?

Между section, aside и nav не накладываются margin, как это исправить? А так же, как сделать что бы footer при перемещении в .container не наезжал section и aside? https://jsfiddle.net/8jaxx1x9/1/

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure, facilis enim debitis commodi sequi tempora dolores suscipit est, eum error rerum laboriosam quaerat quisquam aliquid explicabo beatae quidem ipsam quia?

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum, reiciendis. Excepturi voluptates eum mollitia repellendus.

Ленива Компани!

Не имею понятия как сюда поместить CSS, за помощь благодарен.


Ответ

Вертикальный(боковой) margin никогда не накладывается(не схлопывается), поэтому никак не исправить.
Чтобы футер не наезжал на section и aside при помещении футера в элемент container, необходимо перед футером поместить элемент с свойством clear: both, либо к самому футеру применить это свойство.
Что вам надо почитать, чтобы не возникало таких вопросов:
Статьи о свойстве float и о его воздействии на поведение элементов Статьи о свойстве clear Статьи о схлопывании марджинов Статьи о хаке clearfix
body { font: 600 14px/24px "Open Sans", "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", Sans-Serif; } h1 { font-size: 20px; font-weight: bold; margin-bottom: 6px; } .container:before, .container:after { content: ""; display: table; } .container:after { clear: both; } .container { background: #eaeaed; margin-bottom: 24px; *zoom: 1; } section { float: left; width: 63.197026%; } aside { float: right; width: 29.3680297%; } .container, nav, section, aside, footer { border-radius: 6px; } section, aside, footer { background: #2db34a; color: #fff; margin: 1.858736059%; padding: 20px 0; text-align: center; } section { float: left; width: 63.197026%; } aside { float: right; width: 29.3680297%; } nav { background-color: #2db34a; margin: 1.858736059%; text-align: center; } nav ul { margin: 0px; padding: 5px 0px 5px 0px; } nav ul li { display: inline; padding: 5px 10px 5px 10px; border-radius: 6px; } nav ul li a:link, nav ul li a:visited { color: white; border-bottom: none; font-weight: bold; text-decoration: none; } nav ul li.selected { background-color: lightgreen; font-weight: bold; color: white; } @media all and (max-width: 420px) { section, aside, footer { float: none; width: auto; } }

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure, facilis enim debitis commodi sequi tempora dolores suscipit est, eum error rerum laboriosam quaerat quisquam aliquid explicabo beatae quidem ipsam quia?

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum, reiciendis. Excepturi voluptates eum mollitia repellendus.

Itaque aut in eius repellendus, eaque, quaerat voluptates vero, ipsam recusandae, et unde. Aut, ut?

Eaque maxime eos, doloribus voluptatibus harum placeat, pariatur amet, perspiciatis officia hic corrupti, numquam repudiandae.

Consequuntur aperiam ullam dolores labore veritatis tempore magnam ducimus qui, voluptatum aliquam, dolorem, vel expedita!

Quidem, ipsa aperiam sequi qui. Optio aliquid, sed nisi inventore illo totam quisquam vero sit.

Tenetur reprehenderit minus facilis veritatis debitis quos totam incidunt, excepturi dolores error obcaecati, rerum molestias.

Ab nam ex hic numquam expedita, sint amet voluptate et, modi impedit aut? Incidunt, placeat.

Libero nemo ab saepe iure sed tempora adipisci! Mollitia, ratione delectus. Inventore eos nesciunt consequuntur!

Quos, tempore. Error saepe ullam distinctio modi perspiciatis? Incidunt voluptatum, esse dolorum veniam provident similique!

Fuga, labore, laboriosam aut laudantium officiis hic vitae, cum consectetur dolore, recusandae repellendus quisquam voluptates!

Ленива Компани!

Android: стоит ли стремиться минимизировать количество символов в именах и идентификаторах?

Стоит ли в целях увеличения быстродействия и сокращения занимаемого объёма памяти стремиться минимизироватья количество символов в идентификаторах и именах ресурсов?
Вот пример имён строк от самого длинного, но понятного, до короткого, но требующего задуматься, что это значит:
string name="menu_item_set_everyday_tasks" string name="menui_set_everyday_tasks" string name="menui_seteverydaytasks" string name="menui_setevrdtasks" string name="setevrdtasks" string name="setevrdtsks"
Разумеется, что данное обсуждение значимо, когда мы имеет в одном приложении порядка нескольких сотен ID, строковых ресурсов и т. д.


Ответ

Нет, не нужно. XML-файлы ресурсов не попадают в скомпилировнный код в чистом виде. Вместо этого cреда разработки автоматически преобразовывает строковые имена в числовые идентификаторы и помещает их в виде статических числовых констант в класс R.java. А числовые переменные, как известно, занимают фиксированное количество байт.
Более подробно, например, тут: http://developer.alexanderklimov.ru/android/theory/resources.php#string

Почему плохо перебирать файлы/папки через ls? (Iterating over ls output is fragile. Use globs.)

Есть код, который должен работать в bash и zsh. Фрагмент кода перечисляет все директории, сортируя их по времени последнего изменения. Эту задачу он решает вполне успешно. Перечисляемые директории генерятся тем же кодом и содержат только символы a-zA-Z0-9-_, никаких пробелов.
mcve.sh:
#!/usr/bin/env bash for i in $(ls -dt1 ./*/); do echo "${i}"; done
Использую shellcheck:
shellcheck mcve.sh
Получаю следующий результат:
In mcve.sh line 2: for i in $(ls -dt1 ./*/); ^-- SC2045: Iterating over ls output is fragile. Use globs.
В чём "хрупкость" этого метода? Как я могу его улучшить?
Очевидный вариант "использовать глобы" не подходит, т.к. нужна сортировка по времени.


Ответ

Проблема в том, что ls предназначена в первую очередь для отображения списка файлов в понятном пользователю формате. Это включает всякие метки и прочие обозначения, которые ls прибавляет к наименованиям файлов.
ls -1 не добавляет меток, но это не избавляет от «расцвечивания». Кроме того, работа ls может варьироваться от настроек окружения и операционной системы, что переводит её из разряда «универсальное решение» в разряд «может работать».
Так же не стоит забывать, что совсем нередко пользователи при помощи алиаса задают дефолтные настройки для ls
Для того, чтобы получить некий список файлов и передать его в качестве параметров какой-то другой команде, обычно используют find. Например, чтобы получить список поддиректорию в текущей директории, отсортированный по mtime, можно сделать как-нибудь так:
find . -maxdepth 1 -type d -printf “%C@ %p
" | sort | awk '{print $2}'

Структуры данных Java. LinkedList

Сегодня хотел изучить списки в Джава и возник такой вопрос. Куда заносятся все элементы в списках? Т.е. для организации полноценной структуры данных, значения должны сохранятся в каком-то массиве или что-то типа этого. А куда сохраняются значения в списках?


Ответ

Связный список (LinkedList) - это динамически изменяемая структура данных, которая строится из набора объектов (узлов Nodes), ссылающихся друг на друга (см. рисунок ниже). Каждый узел обычно хранит одну (на следующий узел) или две(на следующий и предыдущий узлы - такой список называется двусвязным) ссылки на соседей и непосредственно значение элемента списка.
Таким образом, значение списка хранится в классах "обертках", которые связаны между собой ссылками.
В самой структуре данных, объекте LinkedList хранятся только две ссылки на первый и последний (в двусвязных списках) элемент списка, а доступ к любому элементу списка можно получить переходя по ссылкам узлов.

Подробнее рекомендую посмотреть в книгах, посвященных алгоритмам и структурам данных, например можно начать с книги "Алгоритмы на Java". Авторы: Роберт Седжвик и Кевин Уэйн.

JavaScript: лишняя итерация цикла do while

Этот код, взятый с javascript.ru, ищет все вхождения подстроки "иа":
var str="Ослик иа-иа посмотрел на виадук"; var poisk="иа"; var i=0; do { var x = str.indexOf(poisk,i); i=x+1; alert(x) } while (x!=-1)
Недостаток этого кода в том, что он проходит одну лишнюю итерацию, когда indexOf уже вернул -1. Я модифицировал этот код следующим образом:
var string = "JavaScript и Java - разные языки!"; var substring = "Java";
var nextDesiredSubstringPosition = 0;
while (desiredSubstringPosition!=-1){ // позиция подстроки, которую мы ищмем var desiredSubstringPosition = string.indexOf(substring, nextDesiredSubstringPosition); if (desiredSubstringPosition === -1 ){break;} nextDesiredSubstringPosition = desiredSubstringPosition + 1;// в следующей итерации начинаем отсюда }
Лишнюю итерацию я убрал, но получается что условие при while никогда не выполняется в строке с этим условием, а выход из цикла осуществляется засчет вложенного if. Программа работает, но код не логичный. Можно ли убрать эту нелогичность, не усложняя код?


Ответ

Почему бы вам не сделать так?
var str = "Ослик иа-иа посмотрел на виадук"; var poisk = "иа"; var x, i = 0; while ((x = str.indexOf(poisk,i)) != -1) { alert(x) i=x+1; }
Внутри условия цикла вычисляем x и тут же его сравниваем.

javascript колбэки

Когда мы передаем функцию в качестве параметра другой функции, мы можем вызвать ее в любой момент внутри содержащей функции, как если бы функция обратного вызова была определена внутри содержащей функции. Это значит, что по сути функция обратного вызова является замыканием. Замыкания имеют доступ к области видимости содержащей функции, а значит могут использовать любые переменные, определенные внутри содержащей функции.
function boo() { alert(a); }
function foo(callback) { var a = 1; callback(); }
foo(boo);
Почему выдает ошибку, ведь
Замыкания имеют доступ к области видимости содержащей функции, а значит могут использовать любые переменные, определенные внутри содержащей функции.


Ответ

Внутри boo (колбэка) видны а и b, но не видно c
function callingFunction(callback) { var c = 4; callback(3); } function containingFunction() { var b = 2; function boo(a) { console.log(a + b); // 5 console.log(typeof c); // undefined } callingFunction(boo); } containingFunction(); console.log(typeof boo); // for @AntonShchyrov

Минимальное значение для float

Какое значение нужно присваивать переменной типа float, чтобы с помощью неё найти максимум: std::numeric_limits::min() или std::numeric_limits::lowest(), или др.?


Ответ

Ну, поскольку о min пишут
min returns the minimum positive normalized value
т.е. это малое положительное число, то, если вы работаете во всем диапазоне - включая отрицательные числа - лучше использовать lowest. Если только положительные - то 0 :)

Взаимодействие с сторонними приложениями

Возможно ли организовать взаимодействие из моего приложения с другими приложениями в Android. Например со Steam приложением (именно мобильным приложением, не веб апи и тд). К примеру, получить код авторизации (чтобы организовать авторизацию без лишних кликов и вводов). Если что, код пишу на Kivy Python. Если нет, то можете подробно расписать, как вообще в Android организованно взаимодействие с другими приложениями.


Ответ

Наткнулся на пример интеграции WhatsApp в своё приложение
Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send."); sendIntent.setType("text/plain"); sendIntent.setPackage("com.whatsapp"); startActivity(sendIntent);
В Web применяются трюки в виде ссылок:
hi
Посмотрите как работает декомпилированный клиент для того чтобы выяснить, есть ли у пакета подобные интерфейсы.

Построение графика c использованием даты

У меня есть файл примерно с таким содержанием:
56 2016-11-18 4 2016-11-19 4 2016-11-20 244 2016-11-21 280 2016-11-22
Я хочу построить график средствами python, который будет показывать зависимость даты от числа из первой колонки. Не могу понять как работать с датой в графиках.


Ответ

Предположим, что данные находятся в файле: D:\temp\.data\594897.csv
Вот решение, использующее Pandas модуль
import pandas as pd import matplotlib.pyplot as plt import matplotlib matplotlib.style.use('ggplot')
fn = r'D:\temp\.data\594897.csv' # читаем CSV/TXT файл (разделённый пробелами) в DataFrame df = pd.read_csv(fn, sep='\s+', header=None, names=['Value','Date'], parse_dates=['Date']) # рисуем график df.plot(x='Date', y='Value', rot=0, figsize=(14, 10), grid=True, marker='o') plt.show()

UPDATE: рисуем график с первого числа месяца:
from pandas.tseries.offsets import *
# добавим в DF строку с первым числом месяца df.loc[len(df)] = [np.nan, df.Date.min() - MonthBegin(1)] # устанавливаем `Date` в качестве индекса и отсортируем индекс df = df.set_index('Date').sort_index()
df.plot(figsize=(14, 10), grid=True, marker='o')

Вычисление значения математического выражения из строки

Есть строка содержащая математическое выражение вида:
1/3+2/3
Есть ли модуль вычисляющий значение таких выражений?


Ответ

Вы можете воcпользоваться eval
eval('1/3+2/3')
вот тут можно почитать https://docs.python.org/3/library/functions.html#eval
Но обычно с такими функциями проблемы с безопасностью в случае если вы получаете строку из вне ( пользовательский ввод например)

Как запустить .bat файл в бэкграунде?

Имеется .bat файл, который при запуске начинает выполнять различные действия в command line. Есть ли возможность сделать так чтоб функционал .bat файла выполнялся, но при этом чтоб сам comand line был в бэкграунде ( вернее говоря чтоб пользователь не видел, разве что только в TaskManager ) ?


Ответ

Средствами командного процессора этого сделать нельзя. Но можно, например, запустить процесс в скрытом окне, используя запускающий VSB-скрипт... хотя разумнее весь батч переписать на VBS или PS.
UPD:
По просьбе ТС подробнее.
Создай на диске C: каталог \Temp. Создай в нём 2 файла.
A.BAT
ping -n 1000 127.0.0.1 > c:\temp\ping.txt
B.VBS
Set WshShell = WScript.CreateObject("WScript.Shell") WshShell.Run "C:\Temp\a.bat",0
Открой Диспетчер задач, перейди на вкладку "Процессы". Запусти файл b.vbs на исполнение (просто двойной клик по нему). Убедись, что:
В процессах появятся, и через некоторое время исчезнут cmd.exe и ping.exe. В каталоге появится файл ping.txt, и, пока не завершатся процессы по п. 1, файл будет заблокирован. В файле сохранён протокол работы утилиты ping. Ни окно CMD, ни окно PING на панели задач не появляется.
И можно не спешить скакать по окнам, пинг будет работать минут 10-15...

DataRow[] + расширение LINQ

Есть массив строк DataRow[] datarows. Одна из колонок имеет имя Sum. Как получить максимальное значение по данной колонке при помощи расширения LINQ? Спасибо.


Ответ

Если оставить в стороне то, что вы работаете с массивом DataRow, а ответить на конкретно поставленный вопрос, то поиск максимального элемента не будет сильно отличатся от поиска элемента в массиве содержащим в себе объекты определенного класса.
Вы можете получить доступ к столбцам DataRow используя индексаторы (по названию столбца или индексу (отсчет от 0)), которые вернут объект типа object.
Также можно добавить ссылку на System.Data.DataSetExtensions.dll и воспользоваться методами расширения Field, которые предоставляют строго типизированный доступ к вашим столбцам.
Таким образом ваш код будет примерно следующим:
var max = datarows .Select(x => x.Field("Sum")) .Max();

Некорректный вывод размерности массива в функции [дубликат]

На данный вопрос уже ответили: Передача статического одномерного массива определённого размера в функцию 6 ответов Уважаемые коллеги!
Компилятор меня не понимает. Общеизвестно, что размерность массива int size = (sizeof(b) / sizeof(*b));Где, b - некоторый массив. Так вот в примере ниже я получаю размерность массива вынося эту команду в отдельную функцию и выполняя эту команду в main
#include "stdafx.h" #include #include
using namespace std;
//Функция которая считает и печатает размерность массива. void ArrLength(int a[]) { int j = (sizeof(a) / sizeof(*a));; //определяем размерность массива cout << "Размерность массива в функции ArrLength = " << j << endl; }
int main() { setlocale(LC_ALL, "Russian");
int b[] = {3, 5, 8, 3, 0, 32, 18, 65}; //объявление некоторого массива int size = (sizeof(b) / sizeof(*b)); //выяснение размерности некоторого массива cout << "Размерность массива size = " << size << endl; ArrLength(b);
system("PAUSE"); return 0; }
К моему глубочайшему удивлению, распечатывает:
Размерность массива size = 8 Размерность массива в функции ArrLength = 2
То есть, даёт два различных ответа. И если с первым я готов согласиться, то второй кажется мне явно ошибочным.
Вопрос: чем можно объяснить наблюдаемое поведение?


Ответ

Параметры функции, объявленные как массивы, неявно упорядочиваются в указатели на типы элементов массивов.
Поэтому следующие объявления функции
void ArrLength(int a[]); void ArrLength(int a[100]); void ArrLength(int *a);
Эквивалентны и объявляют одну и туже функцию, параметром которой будет указатель типа int *
Вы все эти объявления можете одновременно включить в программу, так как одну и ту же функцию можно объявлять (в отличии от определения функции) несколько раз.
Поэтому внутри этой функции
void ArrLength(int a[]) { int j = (sizeof(a) / sizeof(*a));; //определяем размерность массива cout << "Размерность массива в функции ArrLength = " << j << endl; }
параметр функции a имеет тип int * и выражение
sizeof(a) / sizeof(*a)
эквивалентно выражению
sizeof( int * ) / sizeof( int )
и в зависимости от платформы будет равно либо 2 либо 1.
Если вы хотите написать самостоятельно функцию, которая будет возвращать число элементов в массиве, то вам следует написать шаблонную функцию, в которой массив передается по ссылке.
Например
template size_t ArrLength( const T (&a)[N] ) { return N; }
В С++ вы можете воспользоваться структурой std::extent для получения количества элементов в массиве. Например,
#include #include
int main() { int a[4][6];
std::cout << std::extent::value << std::endl; std::cout << std::extent::value << std::endl; }
Вывод программы на консоль
4 6

Когда input заполнен

Добавить класс к label, когда его input заполнен.

Как это можно реализовать на jquery?


Ответ

$('#test1').change(function(){ tmpval = $(this).val(); if(tmpval == '') { $('#lbl1').removeClass('class1'); } else { $('#lbl1').addClass('class1'); } }); .class1 { background: green; }

Преобразование типов для отрицательной строки

Добрый день, подскажите, почему в Javascript минус перед "строкой" превращает ее в число?
Например:
typeof (-"30"); // number; typeof ("30"); // string;
Спасибо!!


Ответ

Согласно спецификации
The unary - operator converts its operand to Number type and then negates it. Negating +0 produces −0, and negating −0 produces +0.

Оператор "Унарный –" преобразует свой операнд к типу Number и затем инвертирует знак. Инвертирование для +0 даст −0, и для −0 - +0
Далее следует алгоритм работы данного оператора
Вычислить выражение Вызвать ToNumber Если результат NaN вернуть NaN Вернуть результат полученный на втором шаге с инвертированным знаком.

Возврат по ссылке/значению примитивных типов

В этом вопросе сказано, что примитивные типы лучше передавать в функцию по значению. Насколько я понимаю, то же верно и для возврата из функции. Тогда почему операторы индексации (например, вектора) возвращают исключительно ссылки, а не специализированны под возврат по значению для фундаментальных типов? Тем более так наверняка будет использована move семантика.
upd то, что я хочу сделать:
#include
template struct A { T x;
T& operator[](int) {return x;} const T& operator[](int) const {return x;} }; template<> struct A { int x;
int& operator[](int) {return x;} int operator[](int) const {return x;} };
int main() { const A a{}; A b{}; //a[0] = 3; b[0] = 3; std::cout << a[0] << ' ' << b[0]; }


Ответ

Если специализировать для всех фундаментальных типов каклй-нибудь стандартный контейнер, который обладает множеством различных методов, то это будет очень не эффективно.
Поэтому оператор индексирования в любом случае возвращает ссылку на объект. Передача по ссылке не является ресурсо-затратной операцией. Объекты при этом не создаются и не копируются. Более того для фундаментальных типов конструктор перемещения, как таковой, не существует. Поэтому и нет никакой необходимости специально перегружать стандартные контейнеры для фундаментальных типов, которых немало.
К тому же получится неоднозначность с определением перегруженного оператора индексации, так как встроенный оператор возвращает всегда lvalue
Есть еще один нюанс. Даже если вы не собираетесь присваивать возвращаемому объекту новое значение, тем не менее у вас может быть необходимость хранить указатели на эти объекты. Например, у вас может возникнуть необходимость создать объект типа std::reference_wrapper допустим с помощью функции std::cref, который будет указывать на исходный объект в контейнере. Если не передавать ссылку на объект из контейнера, то вы не сможете воспользоваться такой возможностью.
Рассмотрите следующий пример
#include #include #include
int main() { const std::vector v = { 3, 2, 4, 5, 1 };
std::vector> rv = { std::cref(v[0]), std::cref(v[1]), std::cref(v[2]), std::cref(v[3]), std::cref(v[4]) };
std::sort(rv.begin(), rv.end(), [](auto &a, auto &b) { return a.get() < b.get(); });
for (int x : v) std::cout << x << ' '; std::cout << std::endl; for (const auto &r : rv) std::cout << r.get() << ' '; std::cout << std::endl; }
Вывод программы на консоль
3 2 4 5 1 1 2 3 4 5
В этой программе объявлен константный вектор. Однако, так как оператор operator [] возвращает ссылку на исходный объект, то можно связать его с объектом std::reference_wrapper, и тем самым представлять элементы исходного вектора упорядочными по различным критериям.
То есть неважно, является ли объект константным или нет, тем не менее нередко необходимо получить на него ссылку, чтобы отслеживать его состояние. Константные объекты могут помимо прочего быть еще и volatile объектами или иметь члены данных с модификатором mutable
Если же возвращать объект по значению из оператора, то связь с исходным объектом будет утеряна, и вы будете иметь дело с копией.

Не перехватывается выброшенное исключение

Вызываю метод, который при искл.чение перебрасывает его наверх, чтобы обработать во внешнем коде
private async void FillCurrentWeather(string place) { XmlSerializer serializer = new XmlSerializer(typeof(Current)); string xml = await GetWeather(CurrentWeatherUrl,place,7); if (xml != null) { try { TextReader reader = new StringReader(xml); Current forecast = (Current)serializer.Deserialize(reader); PlaceName.Content = forecast.City.Name + "," + forecast.City.Country; CurrentWeather.Update(forecast); reader.Dispose(); } catch (InvalidOperationException ex) { throw new InvalidOperationException(ex.Message, ex.InnerException); } } }
Внешний код
try { FillCurrentWeather(place); FillDayWeather(place); FillWeekWeather(place); } catch (InvalidOperationException ex) { MessageBox.Show("Ошибка при обработке данных внешнего сервиса
" + ex.Message); }
Но исключение не обрабатываеися и выскакивает в отладчике. В чем может быть причина?


Ответ

Во время выполнения под отладчиком выпадают все исключения, отмеченные в списке Debug -> Windows -> Exception Settings (Ctrl+Alt+E). Это нормально. Если вы продолжите выполнение программы (F5), то дальше отработают ваши catch блоки.
UPD
С добавление полного кода стала понятна настоящая причина, к которой предыдущий абзац не имеет никакого отношения. Проблема в этом:
async void FillCurrentWeather
Для полного понимания того, как работает async/await, отсылаю к видео. Здесь же вкратце опишу, что происходит при выполнении программы. Итак:
В блоке try внешнего кода вызывается метод FillCurrentWeather(place); Выполнение метода FillCurrentWeather доходит до этой строки и покидает его*:
string xml = await GetWeather(CurrentWeatherUrl,place,7); В блоке try внешнего кода отрабатывают все остальные методы. Метод GetWeather завершает выполнение, продолжается выполнение метода FillCurrentWeather, вываливается исключение. НО! Блок try/catch во внешнем коде уже завершился, он не может поймать это исключение! Поэтому исключение вываливается на самом верхнем уровне как необработанное (UnhandledTaskException).
async void опасны именно по этим причинам:
мы не знаем, когда они на самом деле завершаются соответственно мы не может адекватно реагировать на исключения в таких методах
async void сигнатуру можно использовать только для событий и методов, имеющих событийную семантику, плюс не забывать целиком оборачивать все тело таких методов в try/catch, поскольку если возникнет исключение, вы либо получите необработанное исключение (если возникло в UI потоке), либо, в случае если оно возникло в потоке пула, вы об этом или не узнаете, или это исключение убьет процесс (в случае с .NET 4.0 будет именно так).
Какие у вас варианты решения? В данном случае -- только один: изменить сигнатуру метода на async Task и ожидать завершения этого метода во внешнем коде.
И еще маленький совет: в вашем случае блок try/catch в методе FillCurrentWeather вообще не нужен, поэтому что он по сути ничего не делает. Просто уберите его. (А впредь, если хотите пробрасывать исключения, оборачивая их в другие, всегда включайте исключение целиком, а не его InnerException, которого может и не быть: throw new Exception("This is new exception", e)).

*на самом деле это упрощение, и выполнение продолжится вглубь до того момента, когда вызов уйдет к IO-устройству. Важно лишь, что программа не дожидается завершения этого метода.
UPD2
Чтобы не терять параллелизацию получения данных о погоде, которая невольно достигалась при использовании async void методов, нужно использовать Task.WhenAll
try { var currentTask = FillCurrentWeather(place); var dayTask = FillDayWeather(place); var weekTask = FillWeekWeather(place); await Task.WhenAll(currentTask, dayTask, weekTask); } catch (InvalidOperationException ex) { MessageBox.Show("Ошибка при обработке данных внешнего сервиса
" + ex.Message); }

Iterator и перемещение в одном направлении

Верно ли, что в Java Iterator поддерживает перемещение только в одном направлении? Если да, какие причины легли в именно такое перемещение по коллекциям в Java?


Ответ

Есть Iterator, он однонаправленнный и имеет методы next() и hasNext(), а есть ListIterator, он двунаправленный, в нем есть как next() и hasNext(), так и previous() и hasPrevious(). Какую реализация брать в каком случае - задача программиста. Касательно того, в какой коллекции какой итератор используется в уже реализовннных коллекциях, это вопрос собственно реализации коллекции.

Как сравнить класс и список

Есть класс DB
class DB { private List newList; public string Naimenovanie { get; set; } public string Url { get; set; } }
В дальнейшем я использую List listDB = new List(); чтобы в цикле вставлять экземпляры класса DB
Есть также отдельно список List urls = new List();
Как сравнить элементы класса listDB.Url и urls и удалить из listDB те элементы url которых равен url списка urls
Я вижу это как создание двойного цикла и сравнение элементов. Думаю есть простое решение через linq


Ответ

Чтобы избежать двойного цикла, я бы сложил url, которые надо удалить, в HashSet
var urlSet = new HashSet(urls);
После этого вам достаточно просто
listDB.RemoveAll(db => urlSet.Contains(db.Url));
Это не совсем LINQ, но, думаю, самый быстрый способ, если у вас достаточно большие списки.
Если оба списка маленькие, наверное, скорее будет обойтись без вспомогательного множества:
listDB.RemoveAll(db => urls.Contains(db.Url));
При этом urls.Contains пробегает цикл по списку urls (а вот urlSet.Contains даёт ответ за O(1)).

Оператор switch, нужен ли break после метки default?

Какой смысл в операторе break после метки default, если оператор switch после default итак завершает свою работу?
Часто вижу примеры, как с break так и без после default
switch(number) { case 0: cout << "Too small.
"; break; case 1: cout << "One.
"; break; case 2: cout << "Two.
"; break; case 3: cout << "Three.
"; break; default: cout << "Too large.
"; break; // какой смысл в этом break? }


Ответ

Синтаксически, нет необходимости в самом последнем break, причём неважно в какой секции он находится.
switch(number) { case 1: cout << 1; break; case 2: cout << 2; break; default: case 0: cout << "Мало"; break; case 3: cout << "Много"; /*break;*/ }
По сути, break - это goto на позицию сразу за фигурной скобкой. (А continue на позицию перед ней, но только в циклах) В этом свете, очевидна излишнесть этого оператора.

Однако, этот break всё ещё может быть полезен, если список случаев (case) может изменяться в будущем. При наличии всех break сложнее ошибиться и получить вот такую ошибку:
switch(number) { case 1: cout << 1; break; case 2: cout << 2; break; default: case 0: cout << "Мало"; break; case 3: cout << 3; // При добавлении строчки, забыли добавить пропущенный break case 4: cout << "Много"; }
Это становится более актуальным, если секции не такие тривиальные, и просто окинув взглядом switch не сразу понятно, что к чему относится.

Как сократить данный js (jquery) код?

Здравствуйте. Пожалуйста помогите грамотно сократить данный код, сам не справляюсь:
$('.but-wd').click(function() { $('.hidden-wd').show(); $('.hidden-wf').hide(); $('.hidden-vm').hide(); $('.hidden-mc').hide(); $('.hidden-ca').hide(); $('.hidden-bt').hide(); $('.hidden-hm').hide(); $('.hidden-eye').hide(); $('.hidden-bug').hide(); $('.hidden-bat').hide(); $('.hidden-qa').hide(); $('.prev').hide(); }); $('.but-wf').click(function() { $('.hidden-wd').hide(); $('.hidden-wf').show(); $('.hidden-vm').hide(); $('.hidden-mc').hide(); $('.hidden-ca').hide(); $('.hidden-bt').hide(); $('.hidden-hm').hide(); $('.hidden-eye').hide(); $('.hidden-bug').hide(); $('.hidden-bat').hide(); $('.hidden-qa').hide(); $('.prev').hide(); }); $('.but-vm').click(function() { $('.hidden-wd').hide(); $('.hidden-wf').hide(); $('.hidden-vm').show(); $('.hidden-mc').hide(); $('.hidden-ca').hide(); $('.hidden-bt').hide(); $('.hidden-hm').hide(); $('.hidden-eye').hide(); $('.hidden-bug').hide(); $('.hidden-bat').hide(); $('.hidden-qa').hide(); $('.prev').hide(); }); $('.but-mc').click(function() { $('.hidden-wd').hide(); $('.hidden-wf').hide(); $('.hidden-vm').hide(); $('.hidden-mc').show(); $('.hidden-ca').hide(); $('.hidden-bt').hide(); $('.hidden-hm').hide(); $('.hidden-eye').hide(); $('.hidden-bug').hide(); $('.hidden-bat').hide(); $('.hidden-qa').hide(); $('.prev').hide(); }); $('.but-ca').click(function() { $('.hidden-wd').hide(); $('.hidden-wf').hide(); $('.hidden-vm').hide(); $('.hidden-mc').hide(); $('.hidden-ca').show(); $('.hidden-bt').hide(); $('.hidden-hm').hide(); $('.hidden-eye').hide(); $('.hidden-bug').hide(); $('.hidden-bat').hide(); $('.hidden-qa').hide(); $('.prev').hide(); }); $('.but-bt').click(function() { $('.hidden-wd').hide(); $('.hidden-wf').hide(); $('.hidden-vm').hide(); $('.hidden-mc').hide(); $('.hidden-ca').hide(); $('.hidden-bt').show(); $('.hidden-hm').hide(); $('.hidden-eye').hide(); $('.hidden-bug').hide(); $('.hidden-bat').hide(); $('.hidden-qa').hide(); $('.prev').hide(); }); $('.but-hm').click(function() { $('.hidden-wd').hide(); $('.hidden-wf').hide(); $('.hidden-vm').hide(); $('.hidden-mc').hide(); $('.hidden-ca').hide(); $('.hidden-bt').hide(); $('.hidden-hm').show(); $('.hidden-eye').hide(); $('.hidden-bug').hide(); $('.hidden-bat').hide(); $('.hidden-qa').hide(); $('.prev').hide(); }); $('.but-eye').click(function() { $('.hidden-wd').hide(); $('.hidden-wf').hide(); $('.hidden-vm').hide(); $('.hidden-mc').hide(); $('.hidden-ca').hide(); $('.hidden-bt').hide(); $('.hidden-hm').hide(); $('.hidden-eye').show(); $('.hidden-bug').hide(); $('.hidden-bat').hide(); $('.hidden-qa').hide(); $('.prev').hide(); }); $('.but-bug').click(function() { $('.hidden-wd').hide(); $('.hidden-wf').hide(); $('.hidden-vm').hide(); $('.hidden-mc').hide(); $('.hidden-ca').hide(); $('.hidden-bt').hide(); $('.hidden-hm').hide(); $('.hidden-eye').hide(); $('.hidden-bug').show(); $('.hidden-bat').hide(); $('.hidden-qa').hide(); $('.prev').hide(); }); $('.but-bat').click(function() { $('.hidden-wd').hide(); $('.hidden-wf').hide(); $('.hidden-vm').hide(); $('.hidden-mc').hide(); $('.hidden-ca').hide(); $('.hidden-bt').hide(); $('.hidden-hm').hide(); $('.hidden-eye').hide(); $('.hidden-bug').hide(); $('.hidden-bat').show(); $('.hidden-qa').hide(); $('.prev').hide(); }); $('.but-qa').click(function() { $('.hidden-wd').hide(); $('.hidden-wf').hide(); $('.hidden-vm').hide(); $('.hidden-mc').hide(); $('.hidden-ca').hide(); $('.hidden-bt').hide(); $('.hidden-hm').hide(); $('.hidden-eye').hide(); $('.hidden-bug').hide(); $('.hidden-bat').hide(); $('.hidden-qa').show(); $('.prev').hide(); }); .but button display: inline-block background-color: #fff color: #111 border: none outline: none text-align: center padding: 13px line-height: 0 font-size: em(55px) margin: 0 letter-spacing: -5px +mt(.18s) &:hover, &:focus color: #68ffff text-decoration: none .hidden &-wd, &-wf, &-vm, &-mc, &-ld, &-ca, &-bt, &-hm, &-eye, &-bug, &-bat, &-sad, &-qa display: none

iPhone 4/4S



Ответ

$('.but').on('click', 'button', function(){ $('.portfolio-popup-text span').hide(); $('.hidden-' + $(this).attr('class').split('-')[1]).show(); $('.prev').hide(); });
Как подсказывают в комментарии: при таком подходе может что-то сломаться, если классы добавятся в кнопки. Поэтому в них можно добавить атрибут data и брать уже не класс, а атрибут
Например:

и в JS будет уже:
$(".hidden-" + $(this).data("id")).show();