Страницы

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

воскресенье, 30 июня 2019 г.

Как убрать BOM из файла?

Как консольно (в Unix-like окружении) удалить BOM (byte-order mark, непечатаемый символ в самом начале файла, являющийся необязательной меткой юникода) из файла?


Ответ

Например, с помощью awk:
awk '{if(NR==1)sub(/^\xef\xbb\xbf/, "");print}' < oldfile > newfile

Время проведенное на сайте

Здравствуйте. Хочу сделать чтоб пользователь мог видеть сколько времени всего он провел на сайте в онлайн. Но для того чтоб его вывести его нужно записать в базу. Как делать запросы в базу я знаю, только вот не пойму как его записывать в базу.. чтоли при каждом обновлении страницы пользователям запись делать, или как? Буду благодарен за помощь.


Ответ

Тут есть 2 варианта
1) Время проведённое с момента авторизации на сайте
2) Общее время проведённое на сайте
В первом случае, записываем время авторизации в сессию в формате mktime и высчитываем время
Второй вариант описан выше

Извлечение сплайнов из модели класса GAM (`mgcv::gam`)

Прошу подсказать по следующему вопросу, который является продолжением данного вопроса. Строим аддитивную модель, как показано на примере из справки ?predict.gam
library(mgcv) n <- 200 sig <- 2 dat <- gamSim(1,n=n,scale=sig)
b <- gam(y ~ s(x0) + s(I(x1^2)) + s(x2) + offset(x3), data = dat)
newd <- data.frame(x0=(0:30)/30, x1=(0:30)/30, x2=(0:30)/30, x3=(0:30)/30)
Xp <- predict(b, newd, type="lpmatrix")
################################################################## ## The following shows how to use use an "lpmatrix" as a lookup ## table for approximate prediction. The idea is to create ## approximate prediction matrix rows by appropriate linear ## interpolation of an existing prediction matrix. The additivity ## of a GAM makes this possible. ## There is no reason to ever do this in R, but the following ## code provides a useful template for predicting from a fitted ## gam *outside* R: all that is needed is the coefficient vector ## and the prediction matrix. Use larger `Xp'/ smaller `dx' and/or ## higher order interpolation for higher accuracy. ###################################################################
xn <- c(.341,.122,.476,.981) ## want prediction at these values x0 <- 1 ## intercept column dx <- 1/30 ## covariate spacing in `newd' for (j in 0:2) { ## loop through smooth terms cols <- 1+j*9 +1:9 ## relevant cols of Xp i <- floor(xn[j+1]*30) ## find relevant rows of Xp w1 <- (xn[j+1]-i*dx)/dx ## interpolation weights ## find approx. predict matrix row portion, by interpolation x0 <- c(x0,Xp[i+2,cols]*w1 + Xp[i+1,cols]*(1-w1)) } dim(x0)<-c(1,28) fv <- x0%*%coef(b) + xn[4];fv ## evaluate and add offset se <- sqrt(x0%*%b$Vp%*%t(x0));se ## get standard error ## compare to normal prediction predict(b,newdata=data.frame(x0=xn[1],x1=xn[2], x2=xn[3],x3=xn[4]),se=TRUE)
Возможно ли каким-то образом извлечь из модели в явном виде саму формулу сплайна s(x), которая бы соответствовала форме записи:
yi = β0 + β1 b1 (xi) + β2 b2 (xi) + · · · + βK+3 bK+3(xi)
(James G. et al. - An Introduction to Statistical Learning with Applications in R)
Заметил, что путем умножения коэффициентов coef(mod) на predict(mod, type="lpmatrix") (матрица модели) можно получить предсказанные значения, возвращаемые функцией predict(mod, type="response"). Собственно, проблема в том, что я не могу поставить эти коэффициенты в соответствие степеням переменной x и (x-knot), как это предполагается при записи сплайна в виде комбинации базисных функций. Приведенный пример предсказания значений на основе интерполяции значений из "lpmatrix" служит, согласно справке, для использования модели вне среды R. Означает ли это, что данная реализация GAM не предполагает получения записи модели в явном виде? Есть ли отличия в этом плане в функции gam() из пакета gam, написанного Хасти и Тибширани - создателями методам обобщенных аддитивных моделей? Спасибо.


Ответ

В пакете rms, который является приложением к известной книге Ф. Харрелла, есть функция Function(), которая выдает уравнение поданной на нее модели. К сожалению, объекты класса gam эта функция не принимает. Но в состав rms входят другие функции, которые позволяют подгонять сплайн-модели - возможно, они подойдут и для Ваших целей. Примеры можно посмотреть здесь и здесь

Заполнение массива значениями

У меня есть пара массивов. Нужно занести определенные значения в нужные места. Здесь даже не столько AngularJS нужен, сколько чистый JS: проход по массивам и т.д.
Мои массивы:
$scope.usersNew - массив пользователей с ответами на вопрос анкеты. Структура такая:
id - идентификатор, понятно. user - имя пользователя, questions - массив ответов на вопросы. Его структура следующая:
id вопроса, name вопроса, answer - собственно, ответ. По умолчанию записана строка "No answer" $scope.anss - массив всех ответов из базы данных. Структура (та ее часть, которую я использую):
sessionID - идентификатор сессии, аналог имени пользователя,
questionAnswer - структура, в которой хранится информация о вопросе и ответе. Из нее беру:
question - структура с информацией о вопросе. Я использую только поле id, answer - структура с информацией об ответе. Я использую поле text
Мой код:
// формирование массива пользователей с ответами // проход по пользователя for (var k = 0; k < $scope.usersNew.length; k++) { // проход по ответам for (var i = 0; i < $scope.anss.length; i++) { // принадлежность ответа пользователю if ($scope.anss[i].sessionID == $scope.usersNew[k].user) { // проход по ответам пользователя for (var j = 0; j < $scope.usersNew[k].questions.length; j++) { // соответствие ответов по id вопроса if ($scope.usersNew[k].questions[j].id == $scope.anss[i].questionAnswer.question.id) { // присвоение ответа пользователю $scope.usersNew[k].questions[j].answer = $scope.anss[i].questionAnswer.answer.text; break; break; } } } } }
Дебаггер показал, что в строке присвоения ответа пользователю программа записывает этот ответ сразу всем пользователям, хотя пользователи вроде как перебираются в самом верхнем for
У меня появилась мысль: может, дело в том, как я заполняла первый массив usersNew? Когда записывала в поля answer значение "No answer", это выглядело примерно так:
for (var i = 0; i < $scope.anss.length; i++) { var item = { id: "", user: "", questions: {} } item.id = $scope.anss[i].id; item.user = $scope.anss[i].sessionID; item.questions = $scope.arrForAns; users.push(item); }
Где $scope.arrForAns - массив, созданный таким образом:
$scope.arrForAns = answers.questions; // answers.questions - это массив объектов, который я достала из JSON, там уже есть id и name for (var i = 0; i < $scope.arrForAns.length; i++) { $scope.arrForAns[i].answer = "No answer"; }
Я вроде читала, уже не уверена где, что с присвоением массивов есть загвоздка: что копируются не данные, а ссылки, и, возможно, в памяти лежит один несчастный массив questions на всех пользователей, и он-то и терзается со всех сторон. Или я ошибаюсь, и это я читала о чем-то другом.


Ответ

Да. Для всего, кроме примитивных типов копируется ссылка.
К примитивным типам относятся созданные без использования new числа, строки и bool'ы, а также null и undefined.
PS: Не лень было такой вопрос задавать вместо того, чтобы погуглить про передачу по ссылке?

гугл объяснил в чем дело, но его решение почему-то не помогает
Не очень разобрался со всей структурой, но подозреваю, что это из-за того, что внутри массива тоже ссылки. Ангуляр позволяет сделать глубокую копию при помощи angular.copy
item.questions = angular.copy($scope.arrForAns);

Перенос строк в списке xslt

Уже битый час хочу добавить перенос строки в список,подскажите как это сделать





  • Ответ

    Добавил в начало документа вместо и тег
    заработал.

    Как в XML найти узел по атрибуту и удалить или изменить?

    Как найти узел по атрибуту? Как найти узел по атрибуту и удалить? Как найти узел по атрибуту и изменить атрибут?
    Только без LINQ
    Пример XML-файла.
    System.xml Microsoft 48 Google 48


    Ответ

    1.
    XmlNodeList nodes = xmlDoc.SelectNodes("//element[@name='value']");
    2.
    for (int i = nodes.Count - 1; i >= 0; i--) { nodes[i].ParentNode.RemoveChild(nodes[i]); }
    3.
    XmlNode node = xmlDoc.SelectSingleNode("//element[@name='value']"); node.Attributes[0].Value = newValue;

    Как послать файл и JSON в одном POST-запросе используя тестовый клиент Flask-a?

    Привет,
    В англоязычной версии SO есть вопрос Using Python Requests to send file and JSON in single request. Мне нужно тоже самое, но только лишь с использованием тествого клиента от Flask. Под тестовым клиентом понимаю результат вызова test_client() от инстанса Flask-а.
    Возможно ли это?
    На всякий случай, тестовый клиент получаю так:
    def create_app(configName='default'): result = Flask(__name__) result.config.from_object(config[configName])
    # more lines
    def setUp(self): self.app = create_app(configName='testing') self.app_ctx = self.app.app_context() self.app_ctx.push() db.create_all() self.client = self.app.test_client()


    Ответ

    Примерно так:
    fp = StringIO('my file contents') metadata = {'key1': 'value1', 'key2': 'value2'} client.post( '/upload' data = { 'file': (fp, 'test.txt'), 'data': json.dumps(metadata), } )
    Файл будет доступен как request.files['file'], а данные как request.form['data']

    Изменение слоя в jCanvas

    Рисую, используя jCanvas. Создала текст, который меняет цвет при наведении мыши. Но я использую setLayer, то есть, получается, создаю новый слой. Поэтому новая надпись исчезает при наведении мыши. Непонятно только почему на весь слой, а не только на первый текст.
    Мне нужно, чтобы первый текст по-прежнему менял цвет при наведении мыши, но все остальное оставалось неизменным.
    Демо
    $('canvas').drawText({ fillStyle: 'green', strokeWidth: 2, x: 150, y: 100, fontSize: 48, fontFamily: 'Verdana, sans-serif', text: 'Hello', layer: true, mouseover: function(layer) { $(this).setLayer(layer, { fillStyle:'red', }) .drawLayers(); }, mouseout: function(layer) { $(this).setLayer(layer, { fillStyle:'green' }) .drawLayers(); }, });
    $('canvas').drawText({ x: 150, y: 300, fillStyle: 'green', strokeWidth: 2, fontSize: 34, text: 'Hello' })


    Ответ

    Проблема заключается в том, что у второго текста не установлено свойство layer: true. Как результат - его нет в списке слоёв, и при вызове .drawLayers(); он перестаёт быть видимым.
    Исправленный код:
    var $canvas = $('canvas'); $canvas.drawText({ fillStyle: 'green', strokeWidth: 2, x: 150, y: 100, fontSize: 48, fontFamily: 'Verdana, sans-serif', text: 'Hello', layer: true, mouseover: function(layer) { $(this).setLayer(layer, { fillStyle: 'red' }).drawLayers(); }, mouseout: function(layer) { $(this).setLayer(layer, { fillStyle: 'green' }).drawLayers(); } }); $canvas.drawText({ x: 150, y: 300, fillStyle: 'green', strokeWidth: 2, fontSize: 34, text: 'Hello', layer: true });
    Полный пример в jCanvas Sandbox

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

    Есть тестовое приложение:
    import time from flask import Flask
    app = Flask(import_name=__name__)
    @app.route('/') def test(): time.sleep(5) return 'ok'
    Запускаю gunicorn так:
    (VENV) p2mbot@mbp:~/projects/test/gt$ gunicorn --workers 10 --threads 10 gt:app [2015-07-18 11:23:10 +0300] [13196] [INFO] Starting gunicorn 19.3.0 [2015-07-18 11:23:10 +0300] [13196] [INFO] Listening at: http://127.0.0.1:8000 (13196) [2015-07-18 11:23:10 +0300] [13196] [INFO] Using worker: threads [2015-07-18 11:23:10 +0300] [13199] [INFO] Booting worker with pid: 13199 [2015-07-18 11:23:10 +0300] [13200] [INFO] Booting worker with pid: 13200 [2015-07-18 11:23:10 +0300] [13201] [INFO] Booting worker with pid: 13201 [2015-07-18 11:23:10 +0300] [13202] [INFO] Booting worker with pid: 13202 [2015-07-18 11:23:10 +0300] [13203] [INFO] Booting worker with pid: 13203 [2015-07-18 11:23:10 +0300] [13204] [INFO] Booting worker with pid: 13204 [2015-07-18 11:23:10 +0300] [13205] [INFO] Booting worker with pid: 13205 [2015-07-18 11:23:10 +0300] [13206] [INFO] Booting worker with pid: 13206 [2015-07-18 11:23:10 +0300] [13207] [INFO] Booting worker with pid: 13207 [2015-07-18 11:23:10 +0300] [13208] [INFO] Booting worker with pid: 13208
    Дальше в браузере одновременно открываю 5 вкладок этого тестового сайта. Я ожидаю, что эти вкладки в браузере отобразятся одновременно через 5 секунд, как задано в коде. Но они появляются поочередно, через каждые 5 секунд. Как будто работая все равно в один поток.
    Что я делаю не так? :)


    Ответ

    Я могу воспроизвести поведение в Firefox и Google Chrome. Браузер выполняет только один запрос по заданной ссылке за раз.
    Достаточно, использовать уникальные ссылки, чтобы увидеть, что gunicorn может обслуживать несколько запросов одновременно. Или вручную запустить несколько запросов (в этом случае не важно, одинаковые или разные ссылки).
    Вот Питон скрипт, который выполняет несколько одновременных http-запросов и в то же время открывает те же ссылки в браузере:
    #!/usr/bin/env python import webbrowser from multiprocessing.pool import ThreadPool
    try: from urllib2 import urlopen except ImportError: # Python 3 from urllib.request import urlopen
    urls = ['http://localhost:8000']*5 # same url urls += ['http://localhost:8000?unique=' + str(i) for i in range(5)] # uniq. urls pool = ThreadPool(len(urls) * 2) # make requests concurrently r = pool.map_async(lambda url: urlopen(url).read(), urls) pool.map(webbrowser.open_new_tab, urls) # open tabs in a browser r.get()
    Для тестирования можно использовать, простое wsgi-приложение:
    #file: wsgi_sleep.py import itertools import time
    def app(environ, start_response, ids=itertools.count(1)): status = '200 OK' headers = [('Content-type', 'text/plain')] data = "# request(s) per worker: " + str(next(ids)) headers.append(('Content-Length', str(len(data)))) start_response(status, headers) time.sleep(5) return [data]
    Его можно запустить как:
    $ gunicorn --threads 20 --access-logfile - wsgi_sleep:app
    Результат
    127.0.0.1 - - [18/Jul/2015:19:15:09 +0000] "GET / HTTP/1.1" 200 26 "-" "Python-urllib/2.7" 127.0.0.1 - - [18/Jul/2015:19:15:09 +0000] "GET / HTTP/1.1" 200 26 "-" "Python-urllib/2.7" 127.0.0.1 - - [18/Jul/2015:19:15:09 +0000] "GET / HTTP/1.1" 200 26 "-" "Python-urllib/2.7" 127.0.0.1 - - [18/Jul/2015:19:15:09 +0000] "GET / HTTP/1.1" 200 26 "-" "Python-urllib/2.7" 127.0.0.1 - - [18/Jul/2015:19:15:09 +0000] "GET /?unique=0 HTTP/1.1" 200 26 "-" "Python-urllib/2.7" 127.0.0.1 - - [18/Jul/2015:19:15:09 +0000] "GET /?unique=1 HTTP/1.1" 200 26 "-" "Python-urllib/2.7" 127.0.0.1 - - [18/Jul/2015:19:15:09 +0000] "GET / HTTP/1.1" 200 26 "-" "Python-urllib/2.7" 127.0.0.1 - - [18/Jul/2015:19:15:09 +0000] "GET /?unique=3 HTTP/1.1" 200 27 "-" "Python-urllib/2.7" 127.0.0.1 - - [18/Jul/2015:19:15:09 +0000] "GET /?unique=2 HTTP/1.1" 200 26 "-" "Python-urllib/2.7" 127.0.0.1 - - [18/Jul/2015:19:15:09 +0000] "GET /?unique=4 HTTP/1.1" 200 26 "-" "Python-urllib/2.7" 127.0.0.1 - - [18/Jul/2015:19:15:14 +0000] "GET / HTTP/1.1" 200 27 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0" 127.0.0.1 - - [18/Jul/2015:19:15:14 +0000] "GET /?unique=2 HTTP/1.1" 200 27 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0" 127.0.0.1 - - [18/Jul/2015:19:15:14 +0000] "GET /?unique=4 HTTP/1.1" 200 27 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0" 127.0.0.1 - - [18/Jul/2015:19:15:14 +0000] "GET /?unique=1 HTTP/1.1" 200 27 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0" 127.0.0.1 - - [18/Jul/2015:19:15:14 +0000] "GET /?unique=3 HTTP/1.1" 200 27 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0" 127.0.0.1 - - [18/Jul/2015:19:15:14 +0000] "GET /?unique=0 HTTP/1.1" 200 27 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0" 127.0.0.1 - - [18/Jul/2015:19:15:19 +0000] "GET / HTTP/1.1" 200 27 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0" 127.0.0.1 - - [18/Jul/2015:19:15:24 +0000] "GET / HTTP/1.1" 200 27 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0" 127.0.0.1 - - [18/Jul/2015:19:15:29 +0000] "GET / HTTP/1.1" 200 27 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0" 127.0.0.1 - - [18/Jul/2015:19:15:34 +0000] "GET / HTTP/1.1" 200 27 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0"
    Лог показывает, что запросы от urllib клиента завершаются практически одновременно в то время как запросы от браузера для повторяющихся ссылок происходят последовательно (не связано с network.http.max-connections-per-server, возможно связано с настройками кэширования).

    Как определить id клиента в gwt приложении?

    Есть GWT проект, лежащий на Tomcat-сервере
    В приложении пользователи могут нажать кнопку получить баланс и изменить его - данные приходят и отправляются на сервер, где происходит работа с базой данной. Все работает.
    Но я в самом клиентском коде написал значение id = 1, и получается абсолютно все, кто заходит на сервер приложения, работают с одним и тем же балансом, с одной и той же строчкой в базе данных. Форма авторизации не предусмотрена. Http протокол я не использую, у нас же в gwt асинхронные запросы на сервер.
    Как мне определять id и задавать его конкретно под каждого пользователя?
    Я читал про Cookie, но не знаю, то ли это. Там есть какой-то метод Cookies.getCookie("JSESSIONID"));. Скажите, это то, что надо?
    Если да, то что это за значения jsessionid, ведь там совсем не цифры?
    Если совсем не то, то какие есть еще способы назначать id для каждого клиента, и чтоб он не менялся?


    Ответ

    Это делается примерно так:
    Клиент подключается к серверу; Сервер генерирует уникальный идентификатор и запоминает его и передает клиенту; Клиент в каждом последующем запросе передает этот идентификатор а сервер определяет что это за клиент уже по этому идентификатору.

    Грань между разработчиком программ и разработчиком компиляторов [закрыт]

    В последнее время очень много обсуждений об экономии на спичах, как привести ту или иную конструкцию в move семантике, всякие проблемы конкатенации строк с использованием .reserve и счетчике строк etc.
    Где та самая грань, между разработчиком программ и разработчиком компиляторов? Что должен знать рядовой разработчик о языке? Ведь читать весь стандарт и разбираться в различных тонкостях нужно только разработчикам компиляторов? Или хорошо программировать на c++ не получится не читая весь стандарт?
    Т.е. о чем должен знать рядовой программист, а что оставить разработчикам компиляторов и оптимизаторов?


    Ответ

    Мне кажется, нету однозначной границы. Многие вещи можно улучшать до бесконечности. Например, те же копии можно отоптимизировать при помощи move-семантики, вычисления можно вынести на этап компиляции при помощи «шаблонной магии», расходы на конкатенацию можно обойти, зарезервировав память заранее. Частично это проблема языка и «дырявых» абстракций, частично — недостаточно умный оптимизатор.
    Границу каждый устанавливает для себя, исходя из своих эстетических предпочтений и практических задач. Например, если код представляет собой бизнес-логику, то в нём низкоуровневые оптимизации смотрятся не на месте, и кроме того ненужным образом усложняют и замедляют разработку.
    Поскольку язык большой, программисты обычно знают только часть общей картины, которая попадается им при разработке. Те, кто занимается низкоуровневым кодом и битовыжиманием, часто плохо разбираются в семантике исключений или там многопоточности. Те, кто занимается lock-free-структурами и знают модель памяти до тонкостей, вполне могут плавать в вопросах упаковки структур или шаблонной магии. А те, кто умеет вычислять md5 на этапе компиляции, вполне могут не знать о внутреннем формате и накладных расходах на множественное наследование или плавать в деталях name resolution.
    Язык C++ имеет тенденцию к большому акценту на «мелкую» эффективность, поэтому мне кажется, разрабатывая на нём, стоит уделить таким оптимизациям больше внимания.

    Как расставить узлы произвольного дерева? [закрыт]

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

    в цикле проходим от верхний-левой до верхней-правой и считаем промежутки (в данном случаи это шесть пустых клеточек, которые как говорил ранее по 20, то есть сумма 120); делю сумму полученную на предыдущем шаге на кол-во узлов плюс один (120 / 3 = 40); проверяю на сколько текущий узел (я начинаю с лева на право и по этому текущий узел это тот у которого два ребенка) удален от левого узла-брата (в данном случаи это 80). теперь я вычитаю из 80 - 40 = 40, это значение расстояние на которое я смещу текущую ноду чтобы оказаться в нужном месте. если это значение (40) больше чем то на которое увеличилось расстояние между двумя крайними нодами, то это значение становится меньшим. То есть рассчитал что 40, но оно больше позволенного и по этому значение меняется на 20. перемещаю ноду.

    Повторяю шесть предыдущих шагов для следующей ноды - 1. получаю 60 2. 60 / 2 = 30 3. 40 4. 30 5. 10 6. ...

    Видите как я усреднил? Сначала выяснил что сдвинуть нужно на сорок, но так как на сорок сдвинуть я не могу (нарушится правило для нижних детей, они будут ближе чем на сорок), я сдвигаю на максиму возможное, это двадцать. А потом я сдвигаю уже на десять. Для примера, если бы у первой обрабатываемой ноды не было детей, то картина была бы следующей -
    На тот случай, если у меня сначала идет узел который можно сдвинуть на "сколько-то" (без детей), а после тот который уже нельзя сдвинуть на "сколько-то", то второй я снова сдвигаю на максимум, но при этом выполняю алгоритм с самого начала (точнее с самой последней удачной точки), но на время подменяю самый верхний-правый текущим.
    Я бы показал код, но я не хочу чтобы Вы смотрели его недочеты, а лишь хочу чтобы Вы поняли смысл.
    Вот. Но дальше я столкнулся с следующей проблемой, да и возможно это только одна из ... Входные данные те же, но все ломается. Алгоритма, как я хотел, не получилось, да и придумать я не могу. Ниже конечный результат -
    Что есть у нод indent - значение на которое текущая нода удалена от предыдущей ||->|| leftOffset - это значение на которое я смещаю влево. В самом начале оно ноль rightOffset = это то значение на которое смещаю вправо. И тоже по дефолту ноль.
    Вот. Сами ноды, как обычные ноды, ссыдка на парента, в котором они хранятся в индексированном массиве. Есть методы для получения ноды по индексу и получение самого индекса.


    Ответ

    В общем, нужно расставлять узлы уже по факту, а не извращаться с двиганием в каких-то рамках. Есть обе константы, "братья" и "соседи", причем "соседи" определяет, насколько должны отстоять друг от друга соседние поддеревья на уровнях ниже первого, а "братья" - на первом. Тогда задачу нужно решать снизу вверх: для каждого поддерева вначале выстраиваем каждое из собственных поддеревьев, после чего выстраиваем текущее подерево, вычисляя для каждого следующего поддерева минимальное смещение относительно нуля, при котором на каждом уровне это поддерево не будет мешать уже установленным поддеревьям. В итоге каждое подерево будет иметь параметр "занятый диапазон" на каждом уровне, где у него есть хоть один лист, по нему и будет идти сравнение при размещении текущего поддерева на верхнем уровне.
    Т.е. алгоритм выглядит так:
    BuiltTree buildTree(Tree tree) { BuiltTree[] siblings; foreach (subTree in tree.subTrees) siblings.push(buildTree(subTree)); BuiltTree result=new BuiltTree(); // пустое foreach (sibling in siblings) { int minRightPos=0; for (i=0;iright заполняется следующим образом: Если добавляемое поддерево на i-m уровне не имеет заполненного right, то на i+1-m уровне right не изменяется, если же имеет, то right становится равным присланному offset плюс имеющийся right. left заполняется схожим образом, но заполняется, только если на данном уровне ещё не заполнен - так как новые поддеревья добавляюстя справа, первое поддерево с заданной глубиной установит left этому поддереву. При выполнении positionRoot() весь массив right и left уменьшается на position, после чего в начало массивов добавляется 0.
    Попытаюсь описать разворачивание алгоритма. Для описания дерева буду использовать списки Лиспа, числа - листы, списки - поддеревья. Пример: ((1) (2 3 4 5)) соответствует такому дереву:
    root | *-----* | +-+^+-+ 1 2 3 4 5
    Исходное дерево: (((1) 2) (((3))) ((4 5 6) ((7 8 9) (10)))). Поддеревья из одного листа не рассматриваю, ибо незачем. Поддерево ((1) 2) имеет значение: left=[0,-10,-10]; right=[0,10,-10] и следующий вид:
    * +^+ * 2 | 1
    Звездочки обозначают вершины поддеревьев, так как в списках нет элемента "корень" . Поддерево (((3))) имеет тривиальный вид и значение массивов left=[0,0,0,0]; right=[0,0,0,0]. Поддерево ((7 8 9) (10)) имеет значение массивов left=[0,-30,-50]; right=[0,30,30] и выглядит так:
    * +--^--+ * * +-+-+ | 7 8 9 10
    Из-за того, что поддерево (7 8 9) получило right[1] как 20, а смещение "соседи" 40, второе поддерево было помещено по смещению 60 (0+40+20), а positionRoot был вызван со смещением 30 (=60/2), в итоге левое поддерево провалилось в минус относительно общего кроня на -50. Сборка поддерева 4-10 будет выглядеть так:
    * +---^----+ * * +-+-+ +--^--+ 4 5 6 * * +-+-+ | 7 8 9 10
    Ограничителем положения правого поддерева здесь выступает второй слой, где у (4 5 6) right[1]=20, а left[1] у поддерева -30, итого общее смещение будет 90. На нижнем уровне у левого поддерева нет элементов, поэтому его пропускаем. В итоге positionRoot будет вызван с положением 55, и общий массив выглядит как left=[0,-55,-75,5]; right=[0,55,85,85]. После чего сборка из трех поддеревьев будет выстроена так: первое ставится по смещению 0, второе (((3))) по смещению 50, и большое третье по смещению 50+40+(-75) = 165, и голова будет смещена на 87.5. Итого получится такая картина:
    * +----+---^-------+ * * * +^+ | +---^----+ * 2 * * * | | +-+-+ +--^--+ 1 * 4 5 6 * * | +-+-+ | 3 7 8 9 10
    Из-за округлений в третьем ряду между звездочкой и 4 четыре пробела вместо трех (я считал один символ = 10 точек, но я считал элементы не имеющими ширины, таким образом, вместо 20 и 40 в вопросе нужно ставить константы 40 и 60).
    Надеюсь, понятно объяснил.
    Апдейт: Технически можно после распределения поддеревьев таким образом искать те поддеревья, которые можно подвинуть внутри отображения, не мешая остальным, и если проблема именно тут, то её на самом деле нет, так как после расстановки всех поддеревьев получен наиболее компактный вариант размещения всего дерева в ширину, и если какие-то поддеревья можно двигать, т.е. у них появляется диапазон разрешенных позиций, вы можете использовать имеющийся у вас алгоритм. А то, что дерево в итоге очень громоздкое по ширине, это не является проблемой как таковой.

    Онлайн ACM подобные тестирующие системы

    Я прочитал данную статью про лимиты памяти, и написал некий код, который вычисляет те или иные значения памяти и времени.
    Как я понял, функция clock() измеряет время процессора, которое сильно отличается от того, что выводит мне команда time в шелле. Каким образом в тестирующих системах это отслеживается? Есть куча разных полей типа:
    VmPeak: 11884 kB VmSize: 11884 kB VmLck: 0 kB VmHWM: 1108 kB VmRSS: 1108 kB VmData: 272 kB VmStk: 88 kB VmExe: 16 kB VmLib: 3244 kB VmPTE: 48 kB VmSwap: 0 kB
    Как именно ограничивают ресурсы в тестирующих системах? Вариант с ps aux совсем не годен для коротко работающих программ.


    Ответ

    Обычно измеряется процессорное время. Это то, что time выводит как user
    По памяти - вам нужен показатель VmSize. Или VmPeak - это пиковое значение VmSize. Если хотите считать совсем честно - то надо отнять от него data/stack/exe/lib - это не "использование памяти" в смысле явного выделения в коде.
    Данные по памяти нельзя определить после завершения процесса, так что единственный вариант - достаточно часто опрашивать данные в фоне. Значение VmPeak за долю секунды до завершения кода будет практически актуальным как "максимум использованной памяти". И заодно следить за превышением выделенного времени выполнения.
    Писать свою систему с нуля достаточно тяжело. Посмотрите исходники существующих систем, например ejudge.

    Получить адрес корневой директории в git-репозитории

    Я пишу shell-скрипт для автоматизации работы с Git. Мне нужен способ получить полный или относительный адрес корневой директории проекта при выполнении команды в любой вложенной директории (включая корневую).
    Например, структура проекта, лежащего в Users/nickvolynkin/git-example
    - root/ | - .git/ | - a/ | - b/ | - c/ | - c1/ | - c2/
    cd c/c1/ echo somecommand
    # вариант 1 ../../
    # вариант 2 Users/nickvolynkin/git-example


    Ответ

    Абсолютный путь через rev-parse
    $ echo $(git rev-parse --show-toplevel) Users/nickvolynkin/git-example
    Относительный путь через rev-parse
    $ echo $(git rev-parse --show-cdup) ../../
    Абсолютный путь через alias
    [alias] root = "!pwd"
    в shell-скрипте:
    $ cd Users/nickvolynkin/git-example/c/c1 $ echo `git root` Users/nickvolynkin/git-example
    # отличие от просто pwd: $ pwd Users/nickvolynkin/git-example/c/c1
    Абсолютный путь через временный alias (без регистрации и смс).
    $ echo $(git -c alias.root='!pwd' root)
    Для передачи аргументом в Git
    Если этот адрес необходимо передать аргументом в какую-то из команд Git, то лучше использовать :/
    # из любой папки делает reset на всю рабочую область $ git reset :/
    # то же самое, что и $ git reset $(git rev-parse --show-toplevel)
    Частично основано на ответах из Is there a way to get the git root directory in one command?

    Ошибка при передачи данных из Html.DropDownListFor

    Мне необходимо отобразить из БД в раскрывающий список ФИО, у которых столбец SubjectCode равен 1
    Ege15VM.cs
    namespace WebApplication1.Models { public class Ege15VM { public IEnumerable Participants { get; set; } public string Participant { get; set; }
    public Ege15VM() { cokoEntitiesWAN dataContext = new cokoEntitiesWAN(); Participants = from a in dataContext.ege_15_res_before where a.SubjectCode == 1 select new SelectListItem { Text = a.surname + " " + a.name, Value = a.ParticipantID, Selected = false }; } } }
    Ege15.cshtml
    @model WebApplication1.Models.Ege15VM
    @using (Html.BeginForm()) { Фамилия, Имя участника: @Html.DropDownListFor(x => x.Participant, Model.Participants)


    }
    HomeController.cs
    [HttpGet] public ActionResult Ege15() { var model = new Ege15VM(); return View(model); }
    [HttpPost] public ActionResult Ege15(Ege15VM model) { return View(); }
    Представление нормально отображается и раскрывающий список содержит необходимые ФИО. Но если нажать на "Сформировать отчет", т.е. вызвать POST, выскакивает ошибка:
    Ссылка на объект не указывает на экземпляр объекта
    Сообщение ссылается на строку
    Фамилия, Имя участника: @Html.DropDownListFor(x => x.Participant, Model.Participants)


    Ответ

    Вот эта строчка:
    return View();
    возвращает View, который будет отрендерен на основе ModelData - данных, переданных от клиента. model при этом будет null.
    замените ее на
    return View(model);

    Ошибка при прохождении сертификата Windows Store

    В общем, пытаюсь сделать appx файл через VS. После компиляции пытаюсь пройти сертификацию, валится на таком:
    Проверка конфигурации отладки
    ОШИБКА Конфигурация отладки Обнаружена ошибка: При тестировании конфигурации отладки обнаружены следующие ошибки: Построение двоичного файла FFF.exe выполнено в режиме отладки. Последствия, если проблема не устранена: Магазин Windows Phone не разрешает отлаженные версии приложений. Инструкции по исправлению: Убедитесь, что приложение не связано с отлаженными версиями платформы и создано на основе конфигурации выпуска.
    Суть в чем, Release мод стоит:
    Что вообще VS хочет от меня?


    Ответ

    В общем, проблема была в том что в одном из двух проектов не была выставлена галочка: Optimize code. Пруф на English SO

    Подстановка данных из формы с помощью jquery

    Ситуация: есть серия вопросов для диагностики самочувствия пациентов с хроническим заболеванием, которые оформлены с помощью обычного

    . Вопросы появляются по очереди один за другим. Данные передаются на сервер после ответа на последний вопрос.
    Задача: в некоторые вопросы необходимо подставлять предыдущие ответы. Т.е. подстановка должна происходить еще до того, как данные передались на сервер.
    Как это можно реализовать с помощью jquery?
    Простой пример:
    Здравствуйте! Давайте знакомиться. Как Вас зовут?
    {нужно подставить iac-name}, рады знакомству. На какой email нам выслать результаты анализа?
    После ответа на все вопросы мы вышлем Вам результаты анализа на email {нужно подставить iac-email}. Подскажите, за последние 3 дня у Вас была головная боль?

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


    Ответ

    Как вариант вот так
    $( "#iac-name" ).change(function() { $("#iac-email").text($( "#iac-name" ).val() + ", рады знакомству. На какой email нам выслать результаты анализа?"); });
    Если содержимое
    {нужно подставить iac-name}, рады знакомству. На какой email нам выслать результаты анализа?
    Будет иметь вид
    , рады знакомству. На какой email нам выслать результаты анализа?
    Тогда можно так
    var text = $("#iac-email").text(); $("#iac-email").text($( "#iac-name" ).val() + text);
    Обновление
    Логика такая, что я поместил в переменную text - следующий текст
    , рады знакомству. На какой email нам выслать результаты анализа?
    Затем обновил содержимое добавив введенное имя. Все это выполняется по событию $( "#iac-name" ).change. Писал в комметариях поэтому не исключено что где-то допустил ошибку.
    Для
    {нужно подставить iac-name}, рады знакомству. На какой email нам выслать результаты анализа?
    Метод $("#iac-email").text() должен вернуть
    {нужно подставить iac-name}, рады знакомству. На какой email нам выслать результаты анализа?

    Чтение тегов MP3 без использования сторонних библиотек

    Я видел много статей о том как читать теги mp3 с помощью разных библиотек. Есть ли способ сделать это без их использования? Если можете, поделитесь кодом пожалуйста.


    Ответ

    В библиотеке .NET нет стандартных классов для работы с тегами ID3. Для того, чтобы сделать, что Вы хотите, Вам нужно самим реализовать спецификацию ID3V2 - там 2 документа: "Main Structure" и "Native Frames". В принципе, ничего сложного там нет, но очень много и нудно, поэтому чтобы не городить велосипедов проще взять что-то готовое - например библиотеку taglib-sharp
    Если же Вы всё-таки хотите поковыряться в этом сами, а переводить официальную спецификацию не хочется или сложно, то я в свое время переводил её для себя (ID3v2.4.0-russian-translate). Правда повторюсь, переводил для себя, этот перевод нельзя использовать как официальный и абсолютно достоверный.

    Помимо тега id3v2 в файле mp3 может храниться тег id3v1. Он ущербен, устарел и имеет ряд ограничений, но в некоторых случаях может быть полезен и реализует в 10 строк. Ограничения тега id3v1:
    На поля отводится фиксированное, малое количество символов Кодировка только в ISO 8859-1 Малое количество полей
    Черновая реализация:
    public class Id3v1 { private const string TAGID = "TAG";
    private byte[] tagid = new byte[3]; private byte[] title = new byte[30]; private byte[] artist = new byte[30]; private byte[] album = new byte[30]; private byte[] year = new byte[4]; private byte[] comment = new byte[28]; private byte[] genre = new byte[1]; private byte[] bitrate = new byte[1]; private byte[] duration = new byte[1];
    public string Title { get { return Encoding.Default.GetString(title).TrimEnd('\0'); } }
    public string Artist { get { return Encoding.Default.GetString(artist).TrimEnd('\0'); } }
    public string Album { get { return Encoding.Default.GetString(album).TrimEnd('\0'); } }
    public string Year { get { return Encoding.Default.GetString(year).TrimEnd('\0'); } }
    public string Comment { get { return Encoding.Default.GetString(comment).TrimEnd('\0'); } }
    public byte Genre { get { return genre[0]; } }
    public string Bitrate { get { return Encoding.Default.GetString(bitrate).TrimEnd('\0'); } }
    public string Duration { get { return Encoding.Default.GetString(duration).TrimEnd('\0'); } }
    public Id3v1(string filename) { using (FileStream fs = new FileStream(filename, FileMode.Open)) { fs.Seek(-128, SeekOrigin.End); fs.Read(tagid, 0, tagid.Length);
    //Проверка наличие тега по заголовку "TAG" в начале if (Encoding.Default.GetString(tagid) == TAGID) { fs.Read(title, 0, title.Length); fs.Read(artist, 0, artist.Length); fs.Read(album, 0, album.Length); fs.Read(year, 0, year.Length); fs.Read(bitrate, 0, bitrate.Length); fs.Read(duration, 0, duration.Length); fs.Read(comment, 0, comment.Length); fs.Read(genre, 0, genre.Length); } else { throw new NoId3v1Exception(); } } } }
    Пример использования:
    public void ArtistTest() { string expArtist = "Sting";
    Id3v1 id3 = new Id3v1("test.mp3");
    Assert.AreEqual(expArtist, id3.Artist); }

    Возможно ли сделать вот такой эффект?

    Здравствуйте, можно ли сделать вот такой прямоугольник (изогнутый что ли), на CSS?

    Получилось сделать с помощь наложения с верху и с низу овалов (белого цвета и оранжевого (как и сам блок)) ,но выглядит это не очень красиво: CSS:
    #main::before{ background-color: white; content: ''; position: absolute; top: 100%; left: -54%; transform: translateX(50%)translateY(-50%); width: 104%; height: 65%; border-radius: 50%; } #main::after{ background-color: #FFC107; content: ''; position: absolute; top: -1%; left: -50%; transform: translateX(50%)translateY(-50%); width: 100%; height: 65%; border-radius: 50%; } #main{ border: 1px solid #ffc107; position: absolute; top: 50%; left: 50%; width: 50%; height: 75px; background: #ffc107; transform: translateX(-50%)translateY(-50%); }
    jsfiddle


    Ответ

    Посмотрите в сторону SVG, возможно и с помощью css можно это сделать, но слишком извращенно получится, скорее всего.
    Для работы с SVG можете использовать одну из библиотек:
    Tree.js Svg.js Path.js D3.js
    и др.

    Динамическое добавление checkbox android

    Почему-то добавленный checkbox с помощью этого кода:
    RelativeLayout test = (RelativeLayout)findViewById(R.id.testRelative); CheckBox checkbox = new CheckBox(this); checkbox.setText("completed"); RelativeLayout.LayoutParams RL = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); test.addView(checkbox, RL);
    Имеет иной стиль вывода, чем тот, что добавлен в xml файл этого же активити:

    Отличаются они только фоном. Первый имеет черный фон (тот CheckBox, что задан динамически), второй имеет стандартный синий цвет (CheckBox с XML файла). Мне необходимо, чтобы они были в одном стиле, какие поправки нужно внести, чтобы это реализовать?


    Ответ

    Можно сделать так. Сначала создать layout файл "chbTemplate" с чекбоксом:

    потом inflate этот layout в ваш CheckBox:
    CheckBox myChb = (CheckBox)getLayoutInflater().inflate(R.layout.chbTemplate, null);
    Надеюсь, что это поможет.

    Хранение объемных данных в viewstate asp.net

    У меня есть сайт на asp.net и мне нужно хранить достаточно большие файлы, 2-4 файла каждый до 10 мб между postback'ами. Сейчас я их храню в сесиях, но админ попросил поискать решение менее требовальное к количеству оперативки на сервере.
    Какие есть минусы хранения 40 мб файлов в Viewstate ? Отправляется ли viewstate в запросе с каждым постбеком, даже если она там не используется?


    Ответ

    Viewstate отправляется при каждом запросе и еще шифруется. Хранить в нем такие большие файлы нельзя. Для ускорения работы сайтов есть практика отключения Viewstate совсем.
    Если ваши файлы разделяются между всеми пользователями, то замените хранение в сессии на хранение в Cache
    Так же можно воспользоваться сторонним кеш-сервисом (memcached, redis и тд).
    Для экономии оперативной памяти вы можете хранить ваши временные файлы на диске между запросами. При небольшом объеме оперативки вам придется сделать выбор между производительностью (хранение в памяти любого кеш-сервиса) и загрузкой памяти (хранить на диске).
    Если задача это позволяет, то можно попытаться переделать последовательность работы с файлами исключающую потребность в их хранении между запросами. Например, вначеле мы собираем информацию об обработке файлов от пользователя и только в конце применяем все алгоритмы к данным из файлов.

    T-SQL: Помогите оптимизировать запрос

    Добрый день.
    Есть запрос, который выполняется большое кол-во времени (даже примерно сказать не могу, больше 3ех минут). Таймаут на выполнение запроса стоит 1 мин, потом ее выполнение обрывается. Все индексы построены, в запрос 1 SELECT:
    SELECT p.[personId] as [personId], --r.[innerId], p.inn as ИНН, ps.[firstNameRu] as [Имя рус.], ps.[lastNameRu] as [Фамилия рус.], ps.[middleNameRu] as [Отчество рус.], ps.[firstNameUa] as [Имя укр.] , ps.[lastNameUa] as [Фамилия укр.], ps.[middleNameUa] as [Отчество укр.], ps.[birthday] as [Дата рождения], p.[phone] as Телефон, ( select comment+', ' from dbo.Reason where personId = p.personId for xml path('') ) as Причина, CASE WHEN ps.[lostDate] IS NULL THEN 0 WHEN ps.[lostDate] IS NOT NULL THEN 1 END as [Паспорт потерян], ps.[series] as Серия, ps.[number] as Номер, ps.[office] as [Место выдачи], ps.[dateReceipt] as [Дата выдачи], p.[city] as Город, ps.[address] as Прописка FROM dbo.Person (NOLOCK) p LEFT JOIN dbo.Passport (NOLOCK) ps ON ps.personId = p.personId
    WHERE
    --isnull(inn,0)=isnull(@inn,isnull(inn,0))
    (isnull(inn, 0) = isnull(@inn, isnull(inn,0))) AND (isnull([firstNameRu], 0) = isnull(@firstNameRu, isnull([firstNameRu],0))) AND (isnull([lastNameRu], 0) = isnull(@lastNameRu, isnull([lastNameRu],0))) AND (isnull([middleNameRu], 0) = isnull(@middleNameRu, isnull([middleNameRu],0))) AND (isnull([firstNameUa], 0) = isnull(@firstNameUa, isnull([firstNameUa],0))) AND (isnull([lastNameUa], 0) = isnull(@lastNameUa, isnull([lastNameUa],0))) AND (isnull([middleNameUa], 0) = isnull(@middleNameUa, isnull([middleNameUa],0))) AND ((@birthday is null) or (ps.[birthday] = @birthday)) AND (isnull([phone], 0) = isnull(@contactPhone, isnull(phone,0))) AND ----(@reason is null) or ( ---- CONTAINS(( ---- select comment+', ' from dbo.Reason ---- where personId = p.personId ---- for xml path('') ---- ), @reason) ----)) AND --(@PassportLost is null) or --( --(CASE -- WHEN ps.[lostDate] IS NULL THEN 0 -- WHEN ps.[lostDate] IS NOT NULL THEN 1 --END) = @PassportLost --) AND (isnull([series], 0) = isnull(@passportSeries, isnull([series],0))) AND (isnull([number], 0) = isnull(@passportNumber, isnull([number],0))) AND (isnull([office], 0) = isnull(@ktoVidal, isnull([office],0))) AND ((@PassportReceivingDate is null) or ( [dateReceipt] = @PassportReceivingDate)) AND (isnull([city], 0) = isnull(@City, isnull([city],0))) AND (isnull([address], 0) = isnull(@PassportAdress, isnull([address],0)))
    Смысл запроса: у нас есть 2 связанные таблицы и большое число параметров. по которым может производиться отбор (всего около 15 параметров, причем могут быть заданы не все, а например только 1 фильтр, или 2 и 3ий)
    Подскажите, пожалуйста, как можно оптимизировать запрос?
    Спасибо
    План выполнения запроса показал, что 60% идет поиск в таблице Person:


    Ответ

    Я переписал запрос, и сделал его динамическим. Решило все проблемы. Всем спасибо.

    Получить стиль с xml

    Всем привет работаю на apache poi надо через xml получить стиль ячеек а именно 'объединение'. Сделал таким вот образом
    21 3. Жыл соңына жылжымалы құрам
    А в самом классе
    spreadsheet.addMergedRegion(new CellRangeAddress( records.getMergeR(), records.getMergeR1(), records.getMergeC(), records.getMergeC1()) );
    Есть ли альтернативный способ это сделать?!


    Ответ

    // Объединить ячейки(startRow, endRow, startColumn, endColumn) sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 2));
    тут подробней написано http://www.programru.com/blog/MYTO0ADMwITz.html

    Сортировка слиянием и ub

    void merge(const int* a1, const int* a2, int* buffer, const int& l1, const int& l2) { int a(0), b(0);
    while(a + b < l1 + l2) { if(b >= l2 || a < l1 && a1[a] <= a2[b]) { buffer[a + b] = a1[a]; ++a; } else { buffer[a + b] = a2[b]; ++b; } } }
    Вот это логическое выражение b >= l2 || a < l1 && a1[a] < a2[b], разве не будет ub? тк выполняется && при a не вышедшем за длину массива и при b вышедшем - обращение к a2[b], при неком стечении обстоятельств, это не будет ub? Чтение при выходе за границу массива.


    Ответ

    Условие в jf предложении можно записать как
    if ( ( b >= l2 ) || ( a < l1 && a1[a] < a2[b] ) )
    Согласно Стандарту С (6.5.14 Logical OR operator)
    4 Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares unequal to 0, the second operand is not evaluated
    Поэтому сначала вычисляется левый операнд оператора ||, и только в случае, если результат вычисления равен 0, вычисляется правый операнд оператора.
    Так что в этом условие неопределенного поведения нет.

    Gradient влияет на hover

    Добрый день,подскажите как быть у 1 таблицы сделан градиент и hover.Ховер почему то дико резко происходит, а во втором варианте просто background без градиента и все плавно.Как исправить эту резкость? https://jsfiddle.net/Zkolya_linkoln/rgzzf94o/1/
    #tablemenu1 td { cursor:pointer; background: linear-gradient(to bottom,#00b200,#009900); width:10%; height:45px; vertical-align: middle; border:1px solid #339900; text-align:center; transition: 2s; color:white; font-weight:900; font-family:"Roboto", Arial, sans-serif; } #tablemenu1 td:hover { background: #00b200; box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5); }
    Спасибо!


    Ответ

    При наведении нужно изменять linear-gradient.
    #tablemenu1{ width:100%;} #tablemenu1 td:first-child { border-top-left-radius: 15px; border-bottom-left-radius: 15px; } #tablemenu1 td:last-child { border-top-right-radius: 15px; border-bottom-right-radius: 15px; } #tablemenu1 td { cursor:pointer; background: linear-gradient(to bottom,#00b200,#009900); width:10%; height:45px; vertical-align: middle; border:1px solid #339900; text-align:center; transition: 2s; color:white; font-weight:900; font-family:"Roboto", Arial, sans-serif; } #tablemenu1 td a {color:white;} #tablemenu1 td:hover { //background:#22dd66; background: linear-gradient(to bottom,#00b200,#00b200); //background: #00b200; box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5); } /*------------------------*/ #tablemenu2{ width:100%;} #tablemenu2 td:first-child { border-top-left-radius: 15px; border-bottom-left-radius: 15px; } #tablemenu2 td:last-child { border-top-right-radius: 15px; border-bottom-right-radius: 15px; } #tablemenu2 td { cursor:pointer; background: green; width:10%; height:45px; vertical-align: middle; border:1px solid #339900; text-align:center; transition: 2s; color:white; font-weight:900; font-family:"Roboto", Arial, sans-serif; } #tablemenu2 td a {color:white;} #tablemenu2 td:hover { background: #00b200; box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5); }

    Об Учереждении Аккредитация

    Об Учереждении Аккредитация

    Java, скроллинг

    Пытаюсь с помощью функции setValue заставить вставать verticalScrollBar в нужное положение, все работает. Но в цикле почему-то нет.
    JScrollPane sp = new JScrollPane(); JScrollBar verticalScrollBar = sp.getVerticalScrollBar(); while(iМожет, нужно как то обновлять полосу прокрутки?


    Ответ

    Попробуйте устанавливать положение скролла вот так:
    sp.getViewport().setViewPosition(...);
    И я рекомендую Вам почитать про создание анимации в Swing.
    UPDATE: Вы что-то делаете не так, вот я не поленился, этот способ - работает:
    import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;
    public class Main extends JFrame {
    public static void main(String[] args) throws Exception{ Main main = new Main(); main.setVisible(true); Thread.sleep(1000); main.animateScrollDown(); }
    private final JScrollPane scrollPane = new JScrollPane(new SimpleComponent(750,1200));
    private final Timer scrollTimer = new Timer(10, new TimerListener());
    { add(scrollPane); setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(new Dimension(800, 600)); setLocationRelativeTo(null); }
    private void animateScrollDown() { scrollTimer.start(); }
    private class TimerListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { JViewport viewport = scrollPane.getViewport(); Point viewPosition = viewport.getViewPosition(); viewPosition.y += 1; if (viewPosition.y > viewport.getView().getHeight() - viewport.getHeight()){ scrollTimer.stop(); } else { viewport.setViewPosition(viewPosition); } } }
    private class SimpleComponent extends JComponent{
    Dimension size;
    public SimpleComponent(int width, int height){ size = new Dimension(width, height); setSize(size); setMinimumSize(size); setPreferredSize(size); setMaximumSize(size); }
    @Override protected void paintComponent(Graphics g) { g.drawLine(0, 0, size.width, size.height); } } }

    пятница, 28 июня 2019 г.

    Как сделать выпадающий список произвольной формы?

    Здравствуйте, хотел бы узнать, как решить эту проблему. Есть элемент Expander, который имеет свой стандартный стиль. Использование Data или Path даёт возможно изменить внешний вид окна и саму кнопку для активации этого выпадающего списка при использование Template. Как это возможно сделать и также чтобы выпадающий список был ровно под кнопкой? К примеру: вызов окна в Skype Данные о качестве связи(громкость и тд.).

    Note: знаю, как использовать Data и Path.


    Ответ

    Если надо можно будет дорисовать ^ самому, так как Path точно прорисован по контуру.

    Activity has been destroyed во время FragmentTransaction.commit()

    Пишу небольшую программку для андроида. Мне нужно создать программно фрагменты. Для этого я написал отдельный класс с функциями FragmentWorkHelper.java:
    public class FragmentWorkHelper extends FragmentActivity {
    FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction ft; public MainTopCompositeFragment mtcf = new MainTopCompositeFragment(); public MainCentralCompositeFragment mccf = new MainCentralCompositeFragment(); public MainBottomCompositeFragment mbcf = new MainBottomCompositeFragment();
    public void ReplaceFrag(Fragment f, int container){ ft = fragmentManager.beginTransaction(); ft.replace(container, f); ft.commit(); }
    public void RemoveFrag(Fragment f){ ft = fragmentManager.beginTransaction(); ft.remove(f); ft.commit(); }
    public void AddFrag(Fragment f, int container){ ft = fragmentManager.beginTransaction(); ft.add(container, f); ft.commit(); }
    public void CreateFrag(){ ft = fragmentManager.beginTransaction(); ft.add(R.id.main_top_fragment, mtcf); ft.add(R.id.main_central_fragment, mccf); ft.add(R.id.main_bottom_fragment, mbcf); ft.commit(); } }
    Вызываю функции этого класса из различных мест программы, например в OnCreate() в MainActivity.java:
    protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FragmentWorkHelper fwh = new FragmentWorkHelper(); fwh.CreateFrag(); }
    Но в итоге получаю вот что:
    Process: developers.com.polygon, PID: 27767 java.lang.RuntimeException: Unable to start activity ComponentInfo{developers.com.polygon/developers.com.polygon.MainActivity}: java.lang.IllegalStateException: Activity has been destroyed at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2693) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758) at android.app.ActivityThread.access$900(ActivityThread.java:177) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:145) at android.app.ActivityThread.main(ActivityThread.java:5942) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195) Caused by: java.lang.IllegalStateException: Activity has been destroyed at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1399) at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:637) at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:616) at developers.com.polygon.FragmentWorkHelper.CreateFrag(FragmentWorkHelper.java:43) at developers.com.polygon.MainActivity.onCreate(MainActivity.java:51) at android.app.Activity.performCreate(Activity.java:6289) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
               В чем беда? Почему активити уничтожается? Я пытался засунуть функции в MainActivity, но выходит та же самая ошибка. Очень нужна помощь.


    Ответ

    getSupportFragmentManager возвращает менеджер для взаимодействия фрагментов с activity из которой он вызван. Соответственно ваш хелпер бесполезен т.к. он может управлять фрагментами только внутри своей activity, а не во всех activity вашего приложения. Если хелпер вам так нужен то сделайте так

    public class FragmentWorkHelper{
    private final FragmentActivity activity;
    public FragmentWorkHelper(FragmentActivity activity) { this.activity = activity; }
    public void replaceFrag(Fragment f, int container){ FragmentTransacion ft = activity.getSupportFragmentManager().beginTransaction(); //some work }
    public void removeFrag(Fragment f){ FragmentTransacion ft = activity.getSupportFragmentManager().beginTransaction(); //some work }
    public void addFrag(Fragment f, int container){ FragmentTransacion ft = activity.getSupportFragmentManager().beginTransaction(); //some work } }
    И тогда в activity в методе onCreate() создавайте экземпляр этого хелпера FragmentWorkHelper helper = new FragmentWorkHelper(this).

    Проблема с сохранением canvas

    Есть div, из содержимого этого div формируется canvas,потом я пытаюсь сохранить это в png
    $("#s_img1").click(function (){
    html2canvas($("#tableWrap"), { onrendered: function(canvas) {
    theCanvas = canvas; document.body.appendChild(canvas);
    $("canvas").attr("id", "canv"); $("#img-out").append(canvas);
    } }); var data = document.getElementById("canv").toDataURL();
    $.post("process.php", { imageData : data }, function(data) { window.location = data; });
    var myCanvas = $(document).find('#canv'); var myImg = myCanvas.get(0).toDataURL();

    alert(myImg);
    });
    Проблема в том,что консоль дает ошибку на toDataURL();
    Uncaught TypeError: Cannot read property 'toDataURL' of undefined
    Подскажите в чем проблема? Вот process.php
    $data = substr($_POST['imageData'], strpos($_POST['imageData'], ",") + 1); $decodedData = base64_decode($data); $fp = fopen("canvas.png", 'wb'); fwrite($fp, $decodedData); fclose(); echo "/canvas.png";
    Тут html








    Right click to save me!


    Ответ

    Проблема том, что при вызове var myCanvas = $(document).find('#canv'); элемент canv еще не создано. Так будет работать:
    function CallPost(postdatа) {
    $.post("process.php", {imageData: postdatа}) .done(function (data) { window.location = 'canvas.png'; }); }
    $(document).ready(function() { $("#s_img1").click(function () { html2canvas($("#tableWrap"), { onrendered: function (canvas) { CallPost(canvas.toDataURL()); } }); }); });

    Динамическое добавление полей форм jQuery

    var count_input = 0; function addFiel () { var telnum = parseInt($('#add_field_area').find('div.add:last').attr('id').slice(3))+1; $('div#add_field_area').append('

    '); } function addD () { var tel = parseInt($('#ad_f').find('div.dob:last').attr('id').slice(3))+1; $('div#ad_f').append('
    '); } function deleteField (id) { $('div#add'+id).remove(); } input { height: 20px; margin: 5px; width:400px; } .addbutton { text-align: center; vertical-align:middle; font-size: 13px; width: 283px; border: 1px solid #70A9FD; -webkit-border-radius: 7px; -moz-border-radius: 7px; border-radius: 7px; cursor: pointer; margin: 2px 0 0 110px; color: #326DC5; padding: 4px; background-color:#BED6FF; } .deletebutton { width: 20px; height: 22px; cursor: pointer; margin: 5px; display:inline-block; background: url(delete.png) repeat; background-position: center center; background-repeat: no-repeat; position:absolute; top: 1px; left: 480px; } .add { position:relative; }
    Добавить новое поле

    При нажатии на кнопку ДОБАВИТЬ НОВОЕ ПОЛЕ, добавляем два поля. После этого нажимаем на кнопку ЕЩЕ НОВОЕ для поля №2 и добавление происходит в поле №1 и поле №2. Как сделать чтоб каждому полю соответствовали свои кнопки?


    Ответ

    Использовать всплытие событий и подниматься до нужного контейнера:
    $(document).on('click', ".container .add-group", function() { var container = $(this).closest(".container"); container.append( $("#group-template").html() .replace(/\{\{g\}\}/g, container.children(".group").last().data("i") + 1 || 1) ); }).on('click', ".group .add-field", function() { var group = $(this).closest(".group"); group.append( $("#field-template").html() .replace(/\{\{g\}\}/g, group.data("i")) .replace(/\{\{f\}\}/g, group.children(".field").last().data("i") + 1 || 1) ); }).on('click', ".group .field .remove-field", function() { $(this).closest(".field").remove(); }); section { border: 1px solid; margin: 1em 0; }


    PS: Лучше воспользоваться нормальным шаблонизатором.

    Прочитать с середины файл без чтения его начала на Rust'е

    let f = File::open("file").unwrap(); let reader = BufReader::new(f).seek(io::SeekFrom::Start(2)); for b in reader.iter().next() { println!("{}", b); }
    Выводит то, что находится внутри io::SeekFrom::Start, т.е. 2.


    Ответ

    Какой-то странный цикл у вас. По идее должно быть как-то так:
    let f = File::open("file").unwrap(); let mut reader = BufReader::new(f); reader.seek(io::SeekFrom::Start(2)).unwrap(); for b in reader.bytes() { println!("{}", b); }
    Метод seek() возвращает Result, то есть новую позицию в файле. Он вызывается на &mut self, значит reader должен быть mut, иначе не заработает.
    Что делает ваш код: вы открываете файл и смещаете указатель на 2 байта, сохраняя Result в reader. Потом вы преобразовываете Result в итератор с помощью iter() и вызываете на итераторе next(), получаете Option, равный Some(2). А потом по опции итерируете (Option<_> реализует IntoIterator, так что этому типу можно итерировать). Итератор весело выдаёт один элемент — 2.
    Чтобы избежать подобных ошибок в будущем, внимательно читайте документацию на используемые трейты и типы: ни в трейте Read, ни в типе BufReader нет метода iter(), однако в Read есть метод bytes(), который вам был нужен. А вот метод Seek::seek возвращает Result. Кроме того стоит больше прочитать про интерфейс итераторов, так как вы, судя по всему, до конца не поняли эту идею, раз вызываете на итераторе метод next() явно.

    Реализация синглтона с многократным освобождением ресурсов

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


    Ответ

    А в чём проблема? Ну окружите весь доступ мьютексом. Поскольку вам нужна логика реинициализации, простое решение с Lazy-свойствами не проходит.
    public sealed class Singleton { // классическая реализация из статьи Jon Skeet'а // http://csharpindepth.com/articles/general/singleton.aspx private static readonly Lazy lazy = new Lazy(() => new Singleton());
    public static Singleton Instance { get { return lazy.Value; } }
    private Singleton() { }
    /////////////////// ленивые свойства /////////////////// object accessMutex = new object();
    string lazyProperty; public string LazyProperty { get { lock (accessMutex) return lazyProperty ?? (lazyProperty = CreateLazyProperty()); } }
    public void Reset() { lock (accessMutex) { lazyProperty = null; // обнулите остальные свойства, освободите IDisposable-ресурсы } }
    string CreateLazyProperty() { ... } }

    Определить значение элемента «спиральной матрицы» по его координатам

    Недавно был вопрос об инициализации массива спиральной матрицей. Хотя предложенные решения его решают, интересно решить эту задачу без использования памяти под массив, а именно:
    Написать метод getNum(int s, int x, int y), который принимает три целых параметра — размер квадратной матрицы (s) и координаты позиции в этой матрице (x, y от 0 до s-1) и возвращает число от 1 до s*s, которое должно стоять в соответствующей ячейке «спиральной матрицы» (сматывающейся от левого-верхнего угла к центру по часовой стрелке).
    Тогда задача вывода данной матрицы на экран должна свестись к такому коду (никакой массив не нужен):
    for (int y = 0; y < s; y++) { for (int x = 0; x < s; x++) { System.out.printf("%4d", getNum(s, x, y)); } System.out.println(); }
    Кроме того можно вообще выводить огромные матрицы, в UI-окошке и скроллить мышкой, быстро отрисовывая только видимую часть.
    Как же реализовать такой метод?
    Решения на других языках тоже принимаются.


    Ответ

    Для начала переведём входные координаты x и y в систему координат относительно центра матрицы. Так как размер может быть чётным или нечётным, удвоим координаты, чтобы не возиться с половинками:
    x = 2 * x - s + 1; y = 2 * y - s + 1;
    Скажем, для матрицы 5×5 возможные значения x и y будут -4, -2, 0, 2, 4. А для матрицы 6×6 — -5, -3, -1, 1, 3, 5.
    Дальше определим, на каком квадрате от центра лежит текущая точка. Это просто максимум модуля обеих координат:
    int n = Math.max(Math.abs(x), Math.abs(y));
    Скажем, для квадрата 5×5 значения будут такие:
    4 4 4 4 *4 4 2 2 *2 4 4 2 *0 2 4 4 2 2 2 4 4 4 4 4 4
    Заметим, что внутри текущего квадрата (n-1)*(n-1) записей. Попробуем определить, какое число должно быть на правой-верхней диагонали. Надо из квадрата s*s вычесть квадрат n*n и посмотреть, что получается. Оказывается, надо ещё n вычесть. Вот значения s*s-n*n-n для квадрата 5×5:
    5 5 5 5 *5 5 19 19 *19 5 5 19 *25 19 5 5 19 19 19 5 5 5 5 5 5
    Ура, диагональ получили. С чётной стороной это тоже верно. Теперь посчитаем расстояние от этой диагонали с учётом знака:
    int p = (y + x) / 2;
    Прибавим это расстояние к нашему s*s - n*n - n, получим:
    1 2 3 4 5 2 17 18 19 6 3 18 25 20 7 4 19 20 21 8 5 6 7 8 9
    Отлично, теперь весь правый-верхний треугольник мы правильно выдаём. Чтобы починить левый-нижний, надо для него заменить p на 2*n-p. Точка лежит в левом-нижнем треугольнике, если x < y
    if (x < y) p = 2 * n - p;
    Вот полный код:
    public static int getNum(int s, int x, int y) { x = 2 * x - s + 1; y = 2 * y - s + 1; int n = Math.max(Math.abs(x), Math.abs(y)); int p = (x + y) / 2; if (x < y) p = 2 * n - p; return s * s - n * n - n + p; }

    Нестандартная сериализация/десериализация при помощи newtonsoft json

    Есть следующие классы:
    public sealed class User { public int Id { get; set; } public Schema Extensions { get; set; } }
    public sealed class UserProperty { public string Id { get; set; } public object Value { get; set; } }
    public sealed class Schema { public string Name { get; set; } public List Properties { get; set; } }
    Задается вот так:
    var user = new User { Id = 1, Extensions = new Schema { Name = "urn:scim:schemas:custom:1.0", Properties = new List { new UserProperty { Id = "A", Value = 1} }
    } };
    Необходимо получить json следующего вида:
    { "Id": 1, "urn:scim:schemas:custom:1.0": { "A": 1 } }
    Как это можно сделать при помощи библиотеки newtonsoft? И соответственно потом десериализовать в структуры, описанные выше?


    Ответ

    Вам нужен JsonExtensionDataAttribute. Но тут есть ограничение - насколько я понимаю, он может быть только типа, реализующего IDictionary

    Cast оператор и шаблонные функции

    Предположим у меня есть два шаблонных типа: основной, который будет везде использоваться и вспомогательный, для нужд реализации. И я хочу объявить функцию которая принимает основной тип.
    template struct Usefull;
    template struct Helper { Helper(T i) : v(i) {}
    T v;
    operator Usefull() { return Usefull(v); } };
    template struct Usefull { Usefull(T i) : h(i) {}
    Helper h; void print() { std::cout << h.v << std::endl; } };
    template void foo(Usefull b) { b.print(); }
    И я хочу использовать это вот так:
    int main() { Usefull x(42); foo(x.h); }
    Но возникает ошибка компиляции:
    template argument deduction/substitution failed: 'Helper' is not derived from 'Usefull'
    Использовать static_cast> не желательно, менять или перегружать foo тоже не охота. Есть ли какие-то еще способы заставить Helper хорошо и неявно преобразовываться в Useful?
    То есть пользователь не должен знать с чем он работает на самом деле, Useful и Helper для него должны вести себя одинаково. Может здесь можно использовать наследование, но я не приложу ума как это организовать.


    Ответ

    Согласно примечанию к параграфу №4 в разделе 14.8.2.1 Deducing template arguments from a function call стандарта C++
    [ Note: as specified in 14.8.1, implicit conversions will be performed on a function argument to convert it to the type of the corresponding function parameter if the parameter contains no template-parameters that participate in template argument deduction. Such conversions are also allowed, in addition to the ones described in the preceding list. —end note ]
    В вашем случае соответствующий параметр функции содержит шаблонный параметр, который участвует в выведении шаблонного аргумента. Поэтому вам придется явно указать шаблонный аргумент или явно использовать приведение типов. Например
    Usefull x(42);
    foo(x.h); foo( static_cast>( x.h ));

    MySQL ORDER BY приближенное значение

    Доброго времени суток! Сразу приведу пример чтобы было понятно. На сайте стандартный поиск сортирует по title (названию новости). У нас есть например 2 новости "семь" и "восемь" и если ввести "семь" то выведет в первую очередь "восемь", т.к. у нас сортировка по алфавиту. Как написать поиск более точный? PHP


    Ответ

    Если конкретно надо вот прям сначала те которые начинаются, а потом которые только содержат, то
    WHERE title LIKE 'семь%' ORDER BY title UNION SELECT ... WHERE title LIKE '%семь%' ORDER BY title
    Но вообще то что тебе нужно называется полнотекстовый поиск

    QByteArray во float

    Есть QByteArray, в котором лежат несколько float. Нужно их оттуда вынуть и записать в соответствующие переменные. Пока единственным решением нашел копирование области памяти с помощью memcpy:
    float f1, f2; memcpy(&f1, byteArray.data(), sizeof(float)); memcpy(&f2, byteArray.data()+sizeof(float), sizeof(float));
    Если пытаться использовать QDataStream, то ничего путного не выходит, т.к. он пытается считать не 4 байта, а 8. Какие решения еще можно найти?


    Ответ

    Используйте класс QDataStream и setFloatingPointPrecision()
    QByteArray arr; float f1, f2; QDataStream ds(&arr, QIODevice::ReadOnly); ds.setFloatingPointPrecision(QDataStream::SinglePrecision); ds >> f1 >> f2;
    Чтобы попеременно читать double и float, нужно переключать режим точности.
    QByteArray arr; float f1; double f2; QDataStream ds(&arr, QIODevice::ReadOnly); ds.setFloatingPointPrecision(QDataStream::SinglePrecision); ds >> f1; ds.setFloatingPointPrecision(QDataStream::DoublePrecision); ds >> f2;
    Либо можно читать "сырые" байты:
    QDataStream ds(&arr, QIODevice::ReadOnly); ds.readRawData(reinterpret_cast(&f1), sizeof(f1)); ds.readRawData(reinterpret_cast(&f2), sizeof(f2));

    Выделить в текущей строке всё с первого непробельного символа до последнего

    Допустим, у меня есть строчка кода с отступом
    promocode.discount_amount
    и курсор где-нибудь в районе слова discount_amount
    Чтобы выделить всё важное на строке, например, для заворачивания в скобки, я набираю
    $v^
    Уверен, есть более быстрое решение, но никак не могу его найти.


    Ответ

    Поправка: чтобы переместиться к последнему непробельному символу, надо использовать g_, а не $
    В вашем примере сработает viW (inner WORD, см. :help text-objects). Однако, в общем случае, когда в середине строки могут встречаться пробельные символы, это работать не будет. К сожалению в Vim нет стандартного text-object-а для того, что нам нужно.
    Тут нам на помощь придут mapping-и. Будем использовать для нашего «объекта» буквосочетание il (inner line). Никто не мешает использовать один символ, но тогда скорее придется пожертвовать соответствующей стандартной командой. Следующий mapping для visual mode позволяет сделать то, что нам нужно:
    :vnoremap il :normal! ^vg_
    Теперь при нажатии vil будет выделена «важная» часть строки.
    Опционально: сейчас il работает только в visual mode. Можно заставить его работать со всеми командами Vim, которые ожидают на вход movement или text-object (d, y, c, и т.д.). Для этого используются mapping-и для Operator-pending mode (см. :help omap-info):
    " внимание, в правой части используется mapping il, который мы определили выше :onoremap il :normal vil
    Теперь, в частности, yil копирует «важную» часть строки, а dil — удаляет ее.
    Подробнее почитать, как и почему это работает можно в:
    Главе Operator-Pending Mappings (и след.) в книге Learn Vimscript the Hard Way Статье Creating new text objects Стандартном :help

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

    Есть ли возможность у findimagedupes сравнивать изображения в одной папке с другой?
    Например, в одной папке 100 изображений, и в другой столько же. В первой папке есть одно изображение, более, чем на 85%, похожее на одно изображение в другой папке.
    Я пробовал делать так:
    findimagedupes -t 85 "первая_папка/*" "вторая_папка/*"
    но дело в том, что он показывает совпадения, которые нашлись в первой папке и/или во второй. А надо, чтобы сообщал, что «найдено изображение в папке первая_папка, которое совпадает с изображением во вторая_папка»


    Ответ

    можно в цикле перебрать все пары файлов:
    $ for f1 in первый_каталог/*; do \ for f2 in второй_каталог/*; do \ findimagedupes -t 85 $f1 $f2; done; done

    если же требуется, чтобы в выводимых строках пары файлов не были перемешаны (первым может идти файл то из первого, то из второго каталога), то можно каждую строку отсортировать, воспользовавшись возможностью программы findimagedupes передавать получаемые строки на обработку указанному скрипту (см. man findimagedupes):
    $ for f1 in первый_каталог/*; do \ for f2 in второй_каталог/*; do \ findimagedupes -t 85 -i \ 'VIEW(){ for f in "$@"; do echo $f; done | sort | xargs echo; }' -- \ $f1 $f2; done; done

    такой перебор каждого-с-каждым довольно ресурсоёмок («отпечатки»-fingerprints вычисляются при каждом запуске), поэтому для большей оптимальности следует либо дополнить нужной функциональностью саму программу, либо, вызывая её для всех файлов сразу, несколько усложнить скрипт, передаваемый программе опцией -i

    обновление
    «усложнил» скрипт:
    #!/bin/bash
    d1=$(realpath $1) d2=$(realpath $2)
    e1=$(echo $d1 | sed 's,/,\\/,g')
    findimagedupes -t 85 -i 'VIEW() { n1=$(for f in "$@"; do echo $f; done \ | sed -n "/^'$e1'/{p;q}"); n2=$(for f in "$@"; do echo $f; done \ | grep "^'$d2'" | xargs echo); if [ -n "$n1" -a "$n2" ]; then \ for f in "$@"; do echo $f; done | sed -n "/^'$e1'/!{s|^|$n1 |;p}"; fi; \ }' $d1/* $d2/*
    вызывается он с двумя параметрами: первый_каталог второй_каталог (без каких-либо масок, просто пути к каталогам). для каждой строки, генерируемой программой, он оставляет только один файл из первого каталога (первый встретившийся), но разбивает её на несколько строк так, чтобы в каждой получившейся строке было только по одному файлу из второго каталога.
    например, строку dir1/file1 dir1/file2 dir2/file1 dir2/file2 он заменит на две строки:
    dir1/file1 dir2/file1 dir1/file1 dir2/file2
    и, конечно, строки, в которых присутствуют только файлы из первого или только из второго каталога, игнорируются.

    Странная ошибка в XAML: ошибка при конвертации типа при присваивании через StaticResource

    Не знал как коротко описать суть проблемы.
    Вот код xaml

    Вот код c# класса LocalizedString
    public class LocalizedString : IComparable, ICloneable, IEnumerable, IEquatable, IEquatable { public LocalizedString(string str) { OriginalString = str; }
    public LocalizedString() { OriginalString = ""; }
    public string OriginalString { get; set; }
    public string LocalizeString { get { return InteractiveLocalizer.Localize(OriginalString); } }
    public override string ToString() { return LocalizeString; }
    public int CompareTo(object obj) { if (obj == null) return 1; var str = obj as string; if (str != null) return LocalizeString.CompareTo(str); var lstr = obj as LocalizedString; if (lstr != null) return LocalizeString.CompareTo(lstr.LocalizeString); throw new ArgumentException("LocalizedDtring: Bad type"); }
    public object Clone() { return new LocalizedString(OriginalString); }
    public IEnumerator GetEnumerator() { return LocalizeString.GetEnumerator(); }
    IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
    public bool Equals(string other) { return other == LocalizeString || other == OriginalString; }
    public bool Equals(LocalizedString other) { return OriginalString == other.OriginalString; }
    public static implicit operator LocalizedString(string v) { return new LocalizedString(v); }
    public static explicit operator String(LocalizedString ls) { return ls.LocalizeString; } }
    В данном случае LocalizedString ворачивает ту же самую строку, что и получает "qwe". Я это и ожидал, но во время выполнения прога падает с исключением. Вот текст
    "qwe" не является допустимым значением для свойства "Text".
    Как так?
    Ошибка есть и во время компиляции (хоть она и позволяет запуститься приложению). Вот ее текст
    Не удается применить объект типа "LocalizerLib.LocalizedString" к свойству, для которого требуется тип "System.String".
    В классе определены операторы implict и explict. Чего еще не хватает, чтобы я мог вместо string вставить свой тип?


    Ответ

    XAML игноирирует операторы приведения типа (хоть явные, хоть неявные). Разнообразные конвертеры используются, например, для преобразования результатов биндинга. И даже в этом случае операторы не используются, предпочтение отдаётся ассоциированному TypeConverter (который, впрочем, по умолчанию поддерживает преобразование к строке и просто вызывает ToString). Однако при использовании ресурсов никакой конвертации не производится. Ваш код приводит к вызову:
    object res = new LocalizedString("foo"); fooTextBlock.Text = res;
    С очевидными последствиями.
    Могу предложить несколько путей:
    Вместо странных костылей с ресурсами можно воспользоваться расширениями разметки MarkupExtension. Метод ProvideValue может возвращать произвольный тип и даже учитывать, какому свойству какого объекта значение сейчас присваивается. Выглядеть это в XAML будет кратко и естественно:
    Продолжать городить костыли, но заставить XAML вызвать конвертеры:
    Вообще-то в WPF встроены средства для локализации, но кому до них дело...
    P. S. Код не тестировал, мог наврать.

    Как добавить сервисы Google в Android Studio, чтобы уменшить размер

    Ребята хочу добавить AdMob, но не используя
    compile 'com.google.android.gms:play-services:7.0.0' Так как из за этой команды вес приложение возрастает в 5 раз. До этого весил 700кб, сейчас 5 мегабайт, Это слишком! Есть ли выход? Читал что какой то можно ProGuard задействовать или в Gradle указать чисто для AdMob
    Gradle
    apply plugin: 'com.android.application'
    android { compileSdkVersion 23 buildToolsVersion '23.0.1' defaultConfig { applicationId "com.eranewgames.animevideo" minSdkVersion 10 targetSdkVersion 19 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } productFlavors { } }
    repositories{ flatDir{ dirs 'libs' } }
    dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') compile 'com.mcxiaoke.volley:library:1.0.+' compile 'cz.msebera.android:httpclient:4.4.1.1' compile 'com.android.support:appcompat-v7:23.0.1' }


    Ответ

    Можно подключить отдельно только необходимую часть, полный список тут:
    https://developers.google.com/android/guides/setup
    Для AdMob достаточно com.google.android.gms:play-services-ads:8.1.0

    вторник, 25 июня 2019 г.

    Очередь команд в консоли Linux

    Предположим, что в данный момент в консоли уже выполняется какая-то команда. Она занимает продолжительное время. Я хотел бы выполнить одну или несколько команд после того, как завершится эта. Как это сделать?
    Я знаю, что можно Ctrl + Z и bg, но это не совсем то. Нужно не в бэкграунд отправить команду, а именно дождаться ее завершения.


    Ответ

    используйте не bg (background), а fg (foreground), после которой добавьте нужную команду (команды):
    $ date; sleep 10 Fri Oct 2 10:45:04 MSK 2015 ^Z [1]+ Stopped sleep 10 $ fg; date sleep 10 Fri Oct 2 10:45:14 MSK 2015
    fg и последующую команду можно связать и условиями, например: && или ||