Страницы

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

понедельник, 8 июля 2019 г.

Свойство clip-path через свой path

Добрый день уважаемые. Подскажите, пожалуйста как запускать данное свойство по лично нарисованному пути? (Почему то не выходит, хотя на простых фигурах хорошо отрабатывает) Приведу простой пример
.mainBlock{ width: 180px; height: 245px; } svg{ width: 180px; } .block{ width: 180px; height: 245px; border: 1px solid #000; background: url("https://cdn.rawgit.com/BlackStar1991/Pictures-for-sharing-/ad0580ed/code.jpg?raw=true") no-repeat 50% 50%; -webkit-clip-path: url("#part1"); clip-path: url("#part1"); /// не срабатывает? }


Как "порезать" эти два изображения по тем путям которые нарисованы в svg? Буду очень благодарен, если объясните на этом примере


Ответ

Путь надо вставить в . Ну и предварительно изучить как это свойство вообще работает (например, тут или тут), как надо пути составлять и т. д. С вашим текущим путем обрезает как-то странновато.
.mainBlock { width: 180px; height: 245px; } svg { width: 180px; } .block { width: 180px; height: 245px; border: 1px solid #000; background: url("https://cdn.rawgit.com/BlackStar1991/Pictures-for-sharing-/ad0580ed/code.jpg?raw=true") no-repeat 50% 50%; -webkit-clip-path: url("#clip"); clip-path: url("#clip"); }


Rails SQLite3::ConstraintException: UNIQUE constraint failed: index 'index_users_on_reset_password_token'

Делаю регистрацию с devise
Добавил поле username для User. Для авторизации использую email + pwd.
class ApplicationController < ActionController::Base protect_from_forgery with: :exception before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys:[:username]) end end
class User < ApplicationRecord validates :username, presence: true devise :database_authenticatable, :registerable, :rememberable, :trackable, :validatable end
ActiveRecord::Schema.define(version: 20170228132910) do create_table "users", force: :cascade do |t| t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false t.string "username", default: "", null: false t.datetime "remember_created_at" t.integer "sign_in_count", default: 0, null: false t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" t.string "current_sign_in_ip" t.string "last_sign_in_ip" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["email"], name: "index_users_on_email", unique: true t.index [nil], name: "index_users_on_reset_password_token", unique: true end
end
Первый пользователь зарагистрировался нормально, на втором получаю ошибку
ActiveRecord::RecordNotUnique in Devise::RegistrationsController#create SQLite3::ConstraintException: UNIQUE constraint failed: index 'index_users_on_reset_password_token': INSERT INTO "users" ("email", "encrypted_password", "username", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)
Что там ни так с index_users_on_reset_password_token ?
Добавил миграцию
class DeviseCreateUsers < ActiveRecord::Migration[5.0] def change create_table :users do |t| ## Database authenticatable t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: ""
# Registrable t.string :username, null: false, default: ""
## Rememberable t.datetime :remember_created_at
## Trackable t.integer :sign_in_count, default: 0, null: false t.datetime :current_sign_in_at t.datetime :last_sign_in_at t.string :current_sign_in_ip t.string :last_sign_in_ip
t.timestamps null: false end
add_index :users, :email, unique: true add_index :users, :reset_password_token, unique: true end end


Ответ

Об этом сообщали в баг-трекер Rails (#27782) и это проблема в SQLite:
SQLite has a (mis-)feature that double-quoted names that cannot be resolved to a table or column name are treated as strings. This was a very early design decision, made long before SQLite went viral and found itself running in everything device on the planet, and was intended to make SQLite more compatible with MySQL, which at the time was the most widely deployed database engine in the world. I regret that choice now, but I cannot undo it without breaking backwards compatibility. — D. Richard Hipp, создатель SQLite
По-русски:
У SQLite есть (упоротая) особенность: идентификаторы в двойных кавычках, которые не удалось разрешить в название таблицы или столбца, воспринимаются как строки. Это был осознанный выбор, сделанный задолго до того, как SQLite "выстрелил" и оказался в самых разных устройствах по всему миру, и сделан он был для обеспечения лучшей совместимости с MySQL, в то время самой популярной СУБД в мире. Сейчас я об этом выборе жалею, но избавиться от него, не ломая обратной совместимости, уже не могу.
В Rails вроде полны решимости это поправить на своей стороне, но получится ли у них, вопрос открытый. Нельзя просто так взять и убрать кавычки у колонок в определении индекса. Это исправит именно этот баг, но добавит ограничений на то, какими могут быть имена колонок, а то и просто добавит новых багов.

Вы в миграции добавили уникальный индекс на колонку, которой не существует, reset_password_token. Из-за "особенности" выше в результате получился функциональный (вычисляемый) индекс по константной строке ("reset_password_token"). В результате вы не можете иметь в таблице под этим индексом больше одной строчки, потому что вставка ещё одной потребует добавления в уникальный индекс значения, которое там уже есть. Красота!
Решение сейчас — сделать новую миграцию, в которой стереть этот индекс
remove_index :users, name: :index_users_on_reset_password_token

Нужен совет по написанию игры с постоянным подключением к GPS [закрыт]

Здравствуйте, я собираюсь написать некое подобие игры Pokemon GO. Вместо покемонов обычные точки (на выбор 30), выбрал одну, остальные исчезают, показываются другие игроки, идущие к ней. Успел, пришел, подтвердил местоположение, получил опыт. Не успел, пришел кто-то другой, не получил опыт. Это получается, что подключение к GPS спутникам будет беспрерывное! Беспрерывно должны отправляться координаты игрока, чтобы у других не писались ложные данные. Беспрерывно должен обновляться статус точки (пришли, не пришли). А ведь на улице зарядного устройства нет, а power бланки не у всех имеются, да и телефон будет нагреваться.
Что можно сделать? У меня несколько вопросов в плане реализации
1) Нужно что-то супер точное, чтобы местоположение было максимально правильным
2) Нужно сделать сервис игры безобидным, очень волнуюсь за батареи игроков
3) Если игрок получит травмы, засмотревшись на экран или побежав к точке на дорогу или в чужой дом? Нужно будет лицензионное соглашение?
4) Не забанят ли в GP? Не видел там покемон го, и вообще других аналогов


Ответ

Супер точное местоположение это миф (в Google Maps), даже в Pokemon Go порой разброс большой. Опять же на примере Pokemon Go, батарея улетает очень быстро, а из функций, относящихся к сохранению батареи, только лишь заставка с затемненным экраном, когда опускаешь телефон - то бишь сенсор. В Pokemon Go порой выскакивают диалоги с надписями типа: "Не играйте за рулем", "Смотрите по сторонам". Лиц. соглашение обязательно нужно будет писать т.к. собираетесь хранить местоположение игроков на своем сервере. Не должны
P.S. А вообще трудности будут не сколько с батареей, а с борьбой фейк местоположения. Данный труд выстрелит до первых отзывах о читерах.

contentEditable отступ( tab)

Есть пример ниже. Как сделать так, чтобы при нажатии Tab вставлялся отступ в тексте (абзац) вместо перехода к следующему элементу страницы?

Some text


Ответ

Недавно переделывал для себя подобное из ответа на EN.SO
let divs = document.getElementsByClassName("test"); [].forEach.call(divs, function(item) { item.addEventListener("keydown", function(e) { if (e.keyCode === 9) { e.preventDefault(); let div = this; let selection = div.ownerDocument.defaultView.getSelection(); let range = selection.getRangeAt(0); let tab = document.createTextNode("\u00a0\u00a0\u00a0\u00a0"); range.insertNode(tab); range.setStartAfter(tab); range.setEndAfter(tab); selection.removeAllRanges(); selection.addRange(range); } }) })

Some text

Теряется качество изображения при сохранении с помощью html2canvas

Всем привет. подскажите пожалуйста, где моя ошибка. Задача состоит в том, чтобы сохранить блок в виде изображения. Делаю это следующим образом:
html2canvas($('.gameTable'),{ onrendered: function (canvas) { $('#download').attr('href', canvas.toDataURL("image/png").replace("image/png", "image/octet-stream")); $('#download').attr('download', prefix+'_'+type+'_'+size+'.png'); $('#download')[0].click(); } });
Пробовал и так:
html2canvas($('.gameTable'), { onrendered: function (canvas) { var newCanvas = document.createElement("canvas"); newCanvas.setAttribute('width',1000); newCanvas.setAttribute('height',1000); var ctx = newCanvas.getContext('2d'); ctx.drawImage(canvas,0,0,canvas.width, canvas.height,0,0,1000,1000); var dataURL = newCanvas.toDataURL(); var img = $(document.createElement('img')); img.attr('src', dataURL); $('#download').attr('href', newCanvas.toDataURL("image/png")); $('#download').attr('download', prefix+'_'+type+'_'+size+'.png'); $('#download')[0].click(); } });
В результате получаю изображение плохого качества, во всяком случае, заказчик недоволен. Вот сохраненный скриптов вариант:
Вот сохраненный с помощью Lightshot:
Хотя я сейчас смотрю на прикрепленные изображения и особых различий не вижу, скажите, может есть в моих действиях какая-то ошибка. Всем заранее благодарен.


Ответ

соглано MDN метод канваса toDataURL имеет второй параметр качество:
canvas.toDataURL(type, encoderOptions);
encoderOptions - Число от 0 до 1, указывающее качество изображения.
Так же у этого параметра
Значение по умолчанию - 0,92.
можно, например, поставить canvas.toDataURL("image/jpeg",1)

Удалить или изменить параметр src по клику

Здравствуйте.
Подскажите, как изменить или удалить параметр src по клику? При открытии скрытого блока включается видео, но при закрытии оно продолжает воспроизводиться.
Этим кодом я запускаю видео. Подскажите, как при закрытии окна его остановить.
$(document).on('click', '.open-video', function() { var $video = $('#video'), src = $video.attr('src'); $video.attr('src', src + '?autoplay=1'); });
Пробовал добавить при клике на кнопку
$(document).on('click', '.open-video', function() { var $video = $('#video'), src = $video.attr('src'); $video.attr('src', src + '?pause=1'); });
Но при повторном открытии видео не запускается, в ссылке остаются оба параметра, как удалить ?autoplay=1?


Ответ

Можно заранее очищать ссылку от переменных
$(document).on('click', '.open-video', function() { var $video = $('#video'), src = $video.attr('src').replace(/^(.+)\?.+$/, '$1'); $video.attr('src', src + '?pause=1'); console.log( $video.attr('src') ); });

Как задать константу в padding ссылки

У меня есть константа объявленная как
* { --offset: 10px; }
И я хочу задать, при наведении на ссылку, смещение на константу, чтобы вместо
.menu a:hover { padding: 10px 0 10px 20px; }
я мог написать
.menu a:hover { padding: var(--offset) 0 var(--offset) var(--offset)*2; }
Возможно ли вообще такое реализовать?


Ответ

Проблема оказалась в умножении константы на числовой литерал. Если писать
.menu a:hover { padding: var(--offset) 0 var(--offset) 20; }
то все работает хорошо. Так же к константе можно прибавлять литерал, то есть если написать
.menu a:hover { padding: var(--offset) 0 var(--offset) var(--offset)+10; }
будет тоже работать.

Best Practise - python logger.debug различные yровни логгирования debug

Какие существуют рекомендации по написанию логгирования для режима debug в коде? Как правильно реализовать различные уровни (от 1 до 5 по уровню деталиазации) логгирования для указного режима? Например при включении debug_level <= 3 выводить сообщения в файл логгирования, а если debug_level > 3 тогда выводить debug информацию только на консоль.


Ответ

Привожу простой пример логгирования в консоль и файл с кастомный форматом логов:
def get_logger(name, file='log.txt', encoding='utf8'): import sys import logging
log = logging.getLogger(name) log.setLevel(logging.DEBUG)
formatter = logging.Formatter('[%(asctime)s] %(filename)s[LINE:%(lineno)d] %(levelname)-8s %(message)s')
fh = logging.FileHandler(file, encoding=encoding) fh.setLevel(logging.DEBUG)
ch = logging.StreamHandler(stream=sys.stdout) ch.setLevel(logging.DEBUG)
fh.setFormatter(formatter) ch.setFormatter(formatter)
log.addHandler(fh) log.addHandler(ch)
return log
Пример использования:
log = get_logger('my_log') log.debug('Start')
timeout = 1000 log.info('Timeout %s', timeout)
log.warn('Not found time!') log.error('Error while requests')
log.debug('End')
Результат в консоли и в файле:
[2017-04-03 13:34:25,047] FOO_TEST_TEST.py[LINE:32] DEBUG Start [2017-04-03 13:34:25,047] FOO_TEST_TEST.py[LINE:35] INFO Timeout 1000 [2017-04-03 13:34:25,048] FOO_TEST_TEST.py[LINE:37] WARNING Not found time! [2017-04-03 13:34:25,048] FOO_TEST_TEST.py[LINE:38] ERROR Error while requests [2017-04-03 13:34:25,048] FOO_TEST_TEST.py[LINE:40] DEBUG End

Уровень логирования задается не случайно, это является фильтром, например если в get_logger подправить строку для ch и изменить уровень с DEBUG на ERROR, то в консоль попадут логи с серьезностью от ERROR и выше:
ch = logging.StreamHandler(stream=sys.stdout) ch.setLevel(logging.ERROR)
В консоли будет только:
[2017-04-03 14:04:02,742] FOO_TEST_TEST.py[LINE:40] ERROR Error while requests
В файле будет полный лог как в первом примере

акселлерометр Unity, чувствительность и выход за лимит

Использую следующий код, чтобы получить показания акселлерометра и зафиксировать их максимум.
if (Input.acceleration.y > accelY) { accelY = Input.acceleration.y; } if (Input.acceleration.x > accelX) { accelX = Input.acceleration.x; } if (Input.acceleration.z > accelZ) { accelZ = Input.acceleration.z; }
accelYText.text = "Y = " + accelY.ToString(); accelZText.text = "Z = " + accelZ.ToString(); accelXText.text = "X = " + accelX.ToString();
Проблема в следующем - на разных телефонах есть некий лимит акселлерометра, допустим на моем это 1.90035 по оси х, 2.00055 по оси У и 1.8375 по оси Z. Больше этого значения оно не поднимается. На другом телефоне эти значения тоже около 2, хотя немного отличаются.
Вроде как бы и понятно все, лимит и лимит, но ребята из SmartTools со своим приложением Vibration Meter(не реклама, просто как образец для того, чтобы понять что я хочу) сумели каким то образом настроить чувствительность акселлерометра и мерить большие значения.
Для примера - максимум по их шкале около 13 баллов, но достичь их практически нереально - телефон надо просто бить об стену, чтобы вышло значение больше 11.
А когда меряешь в юнити, то лимит достигается довольно быстро - стукнул телефоном пару раз об подушку и вот они, цифры, выше которых значение не выдает акселлерометр.
Я понимаю что Vibration Meter написан не на Unity, он весит около 7 мб.
Но всё таки интересно - высокая чувствительность акселлерометра и его быстрое достижение максимума - это недоработка юнити, а в оригинальном андроиде всё ок, или есть какой то хитрый способ и в юне понизить чувствительность акселлерометра?
Всё проверялось и писалось под андроид. Возможно как то хелпер-классами android unity получится.


Ответ

Вы путаете величины.
Акселерометр измеряет ускорение.
А Vibration Meter колебания, там используют датчики, но информацию с них обрабатывают, получают интенсивность колебаний и приводят к какой-то из бальных шкал магнитуды землетрясений.

Сделал приложение через AndroidStudio напрямую беру показания с акселерометра. Получаю ускорение в м/с^2. Причем:
sensor.getMaximumRange())
Возвращает на моем телефоне 32. Это значит, что мой датчик не способен зафиксировать более чем 32м/с^2. Но опытным путем доказано, что максимум ~19.5 м/с^2, больше не фиксирует.
Еще одно замечание, в покое никогда не будет 0. Потому что действует ускорение свободного падения. Следовательно на одном из датчиков будет постоянная g, ее значение определенно как константа:
SensorManager.STANDARD_GRAVITY;
Следовательно ее в расчетах необходимо учитывать.

Аппаратные ограничения
Человек может придать своей руке ускорение 5g (50м/с^2) и более. А в телефонах предел измерения акселерометров меньше. Выходит проблема с быстрым достижением максимума не в Unity или Android, а в аппаратной части, достигнут лимит. Попробуйте измерять насколько меняется ускорение
vibration = Math.Abs(previousAccel-Accel)

Получение рывка
Рывок - векторная физическая величина, характеризующая темп (скорость) изменения ускорения тела. Является третьей производной по времени от радиус-вектора.
В примере рассмотрим получение xy части рывка.
Пример на java, выполнять нужно с фиксированным шагом (fixedUpdate() если юнити):
xyAccelPrev = xyAccel;//запоминаем ускорение по XY xyAccel = event.values[0]; //получаем ускорение по XY xyJerk = Math.abs(xyAccel-xyAccelPrev)/4; //получаем рывок по XY где 4 переводной коэфф if(xyJerk > xyJerkMax) xyJerkMax = xyJerk; //фиксируем максимальный рывок по XY xyAverageJerk = (xyAverageJerk+xyJerk)/2; //считаем среднее значение по XY
Вместо 4 можно поставить любое число, изменится диапазон значений.
для других осей аналогичный код. Вычислив по всем трем осям можно свести к вектору и получать его длину. Будет еще сложнее достичь максимального значения.
Чтобы поддерживать максимальное значение (9,75 на моем телефоне) нужно очень быстро перемещать из стороны в сторону, что достаточно сложно, получилось примерно как в Vibration Meter

Получение длины вектора ускорений
Вот как можно расширить диапазон измерения в 1.73, в т.ч. выше предела датчика. Для ускорений, псевдокод:
xyAccel//ускорение по xy xzAccel//ускорение по xz zyAccel//ускорение по zy Accel=sqrt(xyAccel^2+xzAccel^2+zyAccel^2)
Максимум получится достичь, если придать макс ускорение одновременно по всем осям. Аналогично вычисляется и для вектора рывка.

Как динамически отправить форму?

Подскажите как реализовать выход с акк. Есть ссылка и по нажатию отправляется динамически форма, с помощью пост запроса, на указанный url. на указаном url убивается сессия и идет перенаправление на главную страницу. вот код
a(href='', onclick="$('

').submit(); return false") Выйти
на /logout cлед.код
exports.post = function (req, res) { req.session.destroy(); res.redirect('/'); };
но почему вылетает ошибка Form submission canceled because the form is not connected, подскажи те как привязать форму или может как то реализовать это по другому.


Ответ

Сделайте форму частью документа:
$('').appendTo('body').submit();

Смена иконки для неактивной кнопки

Есть стиль для Button c шаблоном в виде иконки и текста, который применяется к нескольким кнопкам:

Когда кнопка неактивна нужно подставить серую иконку (у каждой кнопки, к которой применен стиль, она своя), поэтому я хотел применять стиль следующим образом:

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


Ответ

Вы устанавливаете Tag вручную, а меняете его через стиль. Так, к сожалению, работать не будет: значения, установленные вручную, всегда «сильнее» установленных через стиль, поэтому стиль не может из переопределить.
Устанавливайте начальное значение тоже через стиль.

Документация: https://msdn.microsoft.com/ru-ru/library/ms743230(v=vs.110).aspx

Подключение xsd-схемы к xml файлу

xml
Елизавета Карпова Константиновна СпБГУ
xsd-схема



Оба файла лежат в одной папке.
Ошибка:
Сannot find declaration of element students
Элемент students описан, что не так?


Ответ

Ошибка в том, что xml не соответствует xsd-схеме:

но в xsd-схеме у student нет атрибута id. Схема с добавленным атрибутом id

Построение минимального остовного дерева

Есть построенный граф, в котором все вершины заданы экземплярами класса Vertex, а грани - Edge. Vertex имеют координаты float x и float y, а Edge точки Vertex a и Vertex b, длину double length. Попытка написать алгоритм построения минимального остовного дерева из графа Делоне по алгоритму Прима не увенчалась успехом. Получалось подобное:
Где белые ребра - ребра моего "древа", а серые в совокупности с белыми - исходный граф. Вот код моего алгоритма:
List tmpVertex = points; //вершины графа на входе List tmpEdges = DelanayTree; //ребра графа входе List selectedVertex = new List(); //вершины, по которым "прошелся" алгоритм List selectedEdges = new List(); // окончательный граф (список ребер) selectedVertex.Add(tmpVertex[0]); ///подготовка (чтобы не вызвать исключение) tmpVertex.RemoveAt(0); foreach (Edge e in tmpEdges) //расчет длинны для каждого ребра { e.length = Math.Sqrt((Math.Abs(e.b.x - e.a.x) * Math.Abs(e.b.x - e.a.x)) + (Math.Abs(e.b.y - e.a.y) * Math.Abs(e.b.y - e.a.y))); } while (tmpVertex.Count > 0) //алгоритм будет работать пока есть над чем работать { List conectedEdges = new List(); foreach (Vertex v in selectedVertex) //получение ребер, связывающих выбранные точки { List tmpConnEdges = v.getExtisEgdes(tmpEdges); foreach (Edge e in tmpConnEdges) conectedEdges.Add(e); } Edge minEdge = conectedEdges[0]; //чтобы не вызвать исключение foreach(Edge e in conectedEdges) //поиск ребра с меньшей длиной { if (e.length < minEdge.length) minEdge = e; } selectedEdges.Add(minEdge); //добавление его в финальный граф Vertex nonSelectedVertex; if (minEdge.a.vertexExtisInList(tmpVertex)) nonSelectedVertex = minEdge.a; //поиск второй (не выбранной) вершины этого ребра else nonSelectedVertex = minEdge.b; selectedVertex.Add(nonSelectedVertex); //добавление этой точки в финальный граф tmpEdges.Remove(minEdge); tmpVertex.Remove(nonSelectedVertex); } minimalTree = selectedEdges;
В чем может быть ошибка?


Ответ

Мой алгоритм так и не заработал (возможно из-за того что я его не правильно понял). Вчера нашел другую формулировку этого алгоритма:
Инициализируются списки с данными: ребра, не включенные в дерево, вершины, включенные в дерево, и вершины, не включенные в дерево. выбирается случайная начальная вершина, с которой начнется построение минимального остовного дерева. Цикл while будет продолжаться до тех пор, пока все вершины графа не будут включены в дерево
А в цикле уже: Производится поиск ребра с наименьшим весом, один конец которого – это вершина, входящая в дерево, а другой – нет/ Вершина, инцидентная найденному ребру, заносится в список использованных и удаляется из списка неиспользованных. Найденное ребро заносится в список ребер, составляющих дерево, и удаляется из списка неиспользованных ребер. Переписал код под свои цели:
List notUsedE = new List(DelaunayTree); //неиспользованные ребра есть копия ребер исходного графа List notUsedV = new List(points); //неиспользованные вершины есть копия вершин исходного графа List usedV = new List(); //список вершин по которым "проехался" алгоритм notUsedV[0].inUsedSide = true; //отмечаем что вершина используется usedV.Add(notUsedV[0]); //заносим её в список использованных notUsedV.Remove(usedV[0]); //удаляем из списка неспользованных while (notUsedV.Count>0) //пока есть вершины над которыми можно работать { List doubleSideE = new List(); //создание списка ребер у которых одна вершина используется, а другая нет foreach(Edge e in notUsedE) //для каждого неиспользованного ребра { if ((e.a.inUsedSide && !e.b.inUsedSide) || (e.b.inUsedSide && !e.a.inUsedSide)) doubleSideE.Add(e); //если у него одна вершина исп., а другая нет, то добавляем в список "двуликих" } Edge minE = doubleSideE[0]; //инициализация переменной для ребра, у которого минимальный вес foreach(Edge e in doubleSideE) //для каждого "двуликого" ребра { if (e.weight < minE.weight) minE = e; //если его вес меньше веса минимального, то делаем его минимальным } if (!minE.a.inUsedSide) //если вершина a ребра minE не используется { notUsedV.Remove(minE.a); //то удаляем вершину a из использованных minE.a.inUsedSide = true; //и делам её используемой usedV.Add(minE.a); } else { //а если b не используется notUsedV.Remove(minE.b); minE.b.inUsedSide = true; //то делаем её используемой usedV.Add(minE.b); } minimalTree.Add(minE); //добавляем минимальное ребро в конечный граф notUsedE.Remove(minE); //и удаляем его из неиспользованных, чтобы алгоритм не прошелся по нему еще раз }

Как считывать структуру из файла?

Допустим, у меня есть структура
struct SCHOOL { unsigned long mark; char subject[20]; char surname[20]; short age; };
Для записи её в файл я написал функцию
SCHOOL setInfo() { SCHOOL s; ofstream fout("out.txt", ios::app); cout << "mark: "; cin >> s.mark; cout << "subject: "; cin >> s.subject; cout << "surname: "; cin >> s.surname; cout << "age: "; cin >> s.age; fout.write((char*)&s, sizeof(SCHOOL)); fout.close(); }
Как правильно написать функцию для считывания и потом работать с элементами структуры, например, вывести все фамилии с оценками 9?
Я написал такую функцию,
void getInfo() { SCHOOL s; ifstream fin("out.txt", ios::in); while (!fin.eof()) { fin.read((char*)&s, sizeof(SCHOOL)); } fin.close(); }
Но она работает неправильно.


Ответ

Вот ваша структура
struct School { unsigned long mark; char subject[20]; char surname[20]; short age; };
Вот так лучше писать и читать
void setInfo(School& school) { ofstream fout("out.txt", ostream::binary); //инициализация потока файла //Заполнили структурку cout << "mark: "; cin >> school.mark; cout << "subject: "; cin >> school.subject; cout << "surname: "; cin >> school.surname; cout << "age: "; cin >> school.age; //записали fout.write((char*)&school, sizeof(School)); fout.close(); } void getInfo(School& school) { ifstream fin("out.txt", ios::in); while (!fin.eof()) { fin.read((char*)&school, sizeof(School)); } fin.close(); }
int main() { School school; //так пишем setInfo(school); //так читаем getInfo(school); }
это что касается считывания из файла , далее для работы с множественными объектами струтктуры необходио использовать контейнеры, напрмиер vector или list.
вот пример функции которая запишет в файл все ваши объекты
void recAllSchoolObj(vector vSchool) { ostream fout("out.txt", ostream::binary) for(int i =0; i<=vSchool.size; ++i) { fout.write((char*)&vSchool.at(i), sizeof(School)); } fout.close(); }
вот пример который прочитает
void readAllSchoolObj(vector vSchool) { School school; istream fin("out.txt"); while(!fin.eof) { fin.read((char*)&school, sizeof(School)); vSchool.push_back(school); } fin.close; }
поиск всех фамилий с одной оценкой
void findMark(vector vSchool, unsigned long mark) { cout<<"Surname "< } }

C#. Можно ли используя NLog передать в него значение переменной из кода C#

Имеется некий Updater на C# с используемой библиотекой NLog Updater получает пакеты для обновлений из папок содержащие в своем имени номер версии, например название папки 3.0.14
Допустим в Updater'e была выбрана версия 3.0.14, он будет в дальнейшем работать только с этой папкой и брать оттуда пакеты для обновления окружения.
Вопрос: как заставить NLog писать лог в папку с выбранной версией для обновления, в моем примере хотелось бы писать лог в директорию .../3.0.14/Logs/log-file.txt
Можно ли это сделать с NLog?
Сейчас NLog настроен следующим образом:

В коде:
private static readonly Logger Log = LogManager.GetCurrentClassLogger();


Ответ

Можно настроить NLOG кодом, чтобы он писал строго куда задано и никто не мог переназначить это дело:
var config = new LoggingConfiguration(); var fileTarget = new FileTarget(); config.AddTarget("file", fileTarget); fileTarget.FileName = @"${basedir}/${processname}_${date:format=yyyy_MM_dd}.log"; fileTarget.Layout = @"${date:format=HH\:mm\:ss} ${processid} ${threadid} ${logger} ${message}"; var rule2 = new LoggingRule("*", LogLevel.Debug, fileTarget); config.LoggingRules.Add(rule2); LogManager.Configuration = config;

Сдвиг вправо, сдвиг влево квадрата, и как сделать, чтобы все это было в ограниченном секторе

На картинке консоль разбита на три сектора в большой вывод фигур, и они не должны выходить за рамки. Во втором добавление и перемещение последнего добавленного квадрата. Проблема в том, что я не могу создать этот ограниченный сектор, добавить фигуру и заставить двигаться фигуру. У меня получается вывести на экран фигуру, и все, на этом месте я застрял В Main е добавил клавиши для управления они срабатывают но очень медленно. И иногда выдает такую ошибку как на втором скрине, не знаю как исправить. Сразу извиняюсь за мой русский. Прога профессора как все должно быть
class SahnePaneli { public SahnePaneli(int genislik, int yukseklik) {
} public void KonumAta(int x, int y) {
} public void Ciz() { //функция должна гарантировать, что все четырехугольная (Dortgen) форма, который можно сделать выресуются в область. } public void AktifSekilAta(Dortgen yeniSekil) {
}
public void SekilSolaOtele()// активные функции четырехугольные формы используются для перемещения движущегося блока. {//Каждый шаг должен быть сделан, когда контроль краш-теста.Активная Форма должна быть столкновением с границей ранее добавленных форм и сцен. aktifSekil.SolaOtele(); if (aktifSekil.X == 0) aktifSekil.SagaOtele();
}
public void SekilSagaOtele() { aktifSekil.SolaOtele(); if (aktifSekil.X == 0) aktifSekil.SagaOtele(); }// вправо public void SekilYukariOtele() { }//вверх public void SekilAsagiOtele() { }//вниз public bool SekillerCarpisiyormu() { return false;// на первое время сделал так что бы не мигала }//проверка на то что бы последняя фигура при предвижении не влезла на предыдущюю
private int genislik; private int yukseklik; private int x; private int y; private Dortgen cizimAlani; private Dortgen aktifSekil; private int sekilSayisi; private int maksimumSekilSayisi; private Dortgen[] sekiller; //cizimAlani новый объект используется для рисования границы сцены //sekiller массив должен держать в себе ссылки класса Dikdortgen. размер этого каталога должен быть максимум 100. //maksimumSekilSayi квота вместимости значений из Dortgen. //Это значение должно быть меньше, чем 100. //(Это значение может быть установлено в функции конструктора) //sekilsayi, декорации был добавлен, чтобы указать количество четырехугольника. //Каждый четырехугольник добавляют значение этой переменной должно быть увеличено на 1. //aktifsekil содержит значени Dortgen Последнего добавленного объекта.
} class BilgiPaneli// тут информациооная область (правая нижнея область) { public BilgiPaneli(int genislik, int yukseklik) {
}//тут высота и ширина инфо области //Функция Ciz() рисует поле BilgiPaneli. //Функция BilgiCiz() предоставляет информацию, принадлежащую к активной форме в области рисования BilgiPaneli. //Эта функция должна быть вызвана внутри Ciz(). public void KonumAta(int x, int y) {
} public void Ciz() {
} public void BilgiCiz() {
} public void SekilAta(Dortgen sekil) {
}
private Dortgen aktifSekil; private Dortgen cizimAlani;
private int genislik; private int yukseklik; private int x; private int y;
} class KontrolPaneli//тут панель контроля (верхняя правая область) { //Функция Ciz() рисует поле KontrolPaneli . //Функция MenuCiz() отвечает за прорисовку значений KontrolPaneli //Эта функция должна быть вызвана внутри Ciz(). public KontrolPaneli(int genislik, int yukseklik) {
}
public void Ciz() {
} public void KonumAta(int x, int y) {
} public void MenuCiz() {
}//тут вывод меню
private int genislik; private int yukseklik;
private int x; private int y;
private Dortgen cizimAlani;
} class RastgeleSayi//Рандомное числа { public static int SayiUret(int min, int max) { if (rastgele == null) rastgele = new Random();
return rastgele.Next(min, max); }
private static Random rastgele; } class KarakterSeti // сдесь символы для постройки квадрата { public static char SolUstKose = '╔'; public static char SagUstKose = '╗'; public static char Duz = '═'; public static char Dikey = '║'; public static char SolAltKose = '╚'; public static char SagAltKose = '╝'; } class Dortgen { public Dortgen() // здесь зодается высота и ширина рандомными числами, цвет так же и кординаты так же рандомно { this.genislik = RastgeleSayi.SayiUret(2, 20); this.yukseklik = RastgeleSayi.SayiUret(2, 10); renk = (ConsoleColor)RastgeleSayi.SayiUret(1, 15); x = RastgeleSayi.SayiUret(1, 79); y = RastgeleSayi.SayiUret(1, 79); }
public Dortgen(int xSinir, int ySinir) { this.xSinir = xSinir; this.ySinir = ySinir; } public void ciz() // тут все собирается { ConsoleColor ilkrenk = Console.ForegroundColor; TepeCiz(); DikeyCiz(); TabanCiz(); }
public void DikeyCiz()//сдесь вертикальные столбци { ConsoleColor ilkrenk = Console.ForegroundColor; for (int i = 1; i < yukseklik; i++) { Console.SetCursorPosition(x, y + i); Console.Write(KarakterSeti.Dikey);
Console.SetCursorPosition(x + genislik + 1, y + i); Console.Write(KarakterSeti.Dikey); } Console.ForegroundColor = ilkrenk; } public void TepeCiz()//сдесь нижняя часть квадрата {
Console.ForegroundColor = renk;
Console.SetCursorPosition(x, y);
Console.Write(KarakterSeti.SolUstKose); for (int i = 0; i < genislik; i++) Console.Write(KarakterSeti.Duz); Console.Write(KarakterSeti.SagUstKose);
} public void TabanCiz()//здесь верхняя часть { Console.SetCursorPosition(x, y + yukseklik); Console.Write(KarakterSeti.SolAltKose); for (int i = 0; i < genislik; i++) Console.Write(KarakterSeti.Duz); Console.Write(KarakterSeti.SagAltKose); }
public void SolaOtele()//сдесь я попытался сделать что бы двигалось в право и влево и вниз верх { x -= 1; } public void SagaOtele() { x += 1; } public void YukariOtele() { y -= 1; } public void AsagiOtele() { y += 1; }
public void boyutAta(int genislik, int yukseklik) { this.genislik = genislik; this.yukseklik = yukseklik; } public void RenkAta(ConsoleColor renk) { this.renk = renk; }
private int genislik; private int yukseklik; private ConsoleColor renk; private int x; private int y; private int xSinir; private int ySinir;
public int X { get{ return x; } } public int Y { get { return y; } }
} class Program { static void Main(string[] args) { Dortgen dkg = new Dortgen(); while (true) {
if (Console.ReadKey(true).Key == ConsoleKey.W) { dkg.YukariOtele(); } else if (Console.ReadKey(true).Key == ConsoleKey.A) { dkg.SolaOtele(); } else if (Console.ReadKey(true).Key == ConsoleKey.D) { dkg.SagaOtele(); } else if (Console.ReadKey(true).Key == ConsoleKey.S) { dkg.AsagiOtele(); } Console.Clear(); dkg.ciz();
} } }


Ответ

Из вашего вопроса, я понял что у вас две проблемы.
Скорость вывода и реакции консоли. Об этом я уже отвечал тут, оставлю ссылку на ответ. В принципе, все необходимое там описано, надеюсь с чтением проблем не возникнет, если что оставьте комментарий, постараемся найти взаимно понятный язык. Про особенности работы с консолью Вычисление допустимых размеров и координат фигуры, чтобы она не вылетала за границы отведенной области.
Для исправления ошибки, достаточно немного изменить параметры генерации фигур.
public Dortgen() { this.genislik = RastgeleSayi.SayiUret(2, 20); this.yukseklik = RastgeleSayi.SayiUret(2, 10); renk = (ConsoleColor)RastgeleSayi.SayiUret(1, 15); x = RastgeleSayi.SayiUret(1, areaWidth - this.genislik + 1); y = RastgeleSayi.SayiUret(1, areaHeight - this.yukseklik + 1); }
где: areaWidth - ширина области вывода, меньше либо равно Console.WindowWidth areaHeight - высота области вывода меньше либо равно Console.WindowHeight
аналогично проверяем пару (x,y) на допустимость значений.
if((x > 0) && (x < areaWidth - this.genislik + 1) && (y > 0) && (y < areaHeight - this.yukseklik + 1)) { //логика движения или чего-то еще }

SVG формы периодически не прорисовываются

Есть svg-лого у сайта, состоящее из изображения и текста. На сайте есть 6 страниц. При переходе со страницы на страницу случается так, что текст не отображается либо частично (не прорисовываются 1-2 буквы), либо полностью. Картинка при этом отображается всегда. SVG текст преобразован в кривые path, и объединён тегом . Всё изображение вставлено на сайт инлайново и подключается к хедеру посредством тега use. Так же на сайте есть пару svg-иконок и стрелочек, но с ними такого не происходит. И это случается только на внешнем хостинге, на локальном серваке такого не замечено. Какие могут быть причины такого поведения svg-текста? Есть какие-то предположения?


Ответ

Проблема решилась переносом SVG-спрайта в хедер, до использования его элементов тегом use. Всем спасибо за внимание!

C# и .NET. Какой метод будет менее ресурсозатратный и какой будет быстрее выполняться?

Добрый день! Я новичок в .NET и я задался вопросом (вопрос чисто на интерес и не имеет никакой практической цели): Какой из методов для вывода массива лучше использовать:
Который будет в цикле на каждый элемент вызывать метод Console.Write($"{element} ") Который будет использовать класс StringBuilder и вызывать в цикле на каждой итерации метод Append(element) и Append(' ') и в конце вызовет 1 метод Console.WriteLine();
P.S. Проблемы с созданием списка в вопросе. Вроде как делаю все по инструкции, а список не создается.
UPD. Методы, про которые я говорю:
Метод 1
private static void PrintArray(T[] Array) { foreach (T item in Array) { Console.Write($"{item} "); }
Console.WriteLine(); }
Метод 2
private static void PrintArray(T[] Array) { StringBuilder stringBuilder = new StringBuilder();
foreach (T item in Array) { stringBuilder.Append(item); stringBuilder.Append(' '); }
Console.WriteLine(stringBuilder.ToString()); }


Ответ

Хм... Со StringBuilder получается 36 МС, а без него 523 МС.
Вот код для тестирования:
static void Main(string[] args) { const int len = 1000; //Размер массива string[] arr = new string[len]; for (int i = 0; i < arr.Length; i++) { arr[i] = "blablablabla"; } StringBuilder strBuilder = new StringBuilder(); int counter = 0; var stopWatch1 = new Stopwatch(); stopWatch1.Start(); for (int i = 0; i < arr.Length ; i++) { if (counter>=100|| i== arr.Length - 1) //Пуляем по 100 элементов в консоль { Console.Write(strBuilder.ToString()); strBuilder.Clear(); counter = 0; } counter++; strBuilder.Append("
" + arr[i]); } stopWatch1.Stop(); var stopWatch2 = new Stopwatch(); stopWatch2.Start(); for (int i = 0; i < arr.Length; i++) { Console.WriteLine(arr[i]); } stopWatch2.Stop(); Console.WriteLine($"StringBuilder MS={stopWatch1.ElapsedMilliseconds}"); Console.WriteLine($"Без StringBuilder MS={stopWatch2.ElapsedMilliseconds}"); Console.ReadKey(); } }
Однако, не стоит пытаться все подряд оптимизировать и оптимизацией следует заниматься только в том случае, если это критическая точка программы.
Есть знаменитая фраза:
Преждевременная оптимизация — корень всех зол

В комментария меня поправили и на самом деле автору хотелось выводить строку не порциями, как я тестировал, а агрегировать ее в StringBuilder, а потом за один раз вывести.
В этом случае первый цикл будет таким:
for (int i = 0; i < arr.Length ; i++) { strBuilder.Append("
" + arr[i]); } Console.Write(strBuilder.ToString());
В итоге скорость на 1000 элемента изменилась с 36 МС до ~20 МС.
Но нужно иметь в виду, что консоль не бесконечная и если я не ошибаюсь, то одновременно в них может находится ~8000 символов => пытаясь вывести за раз большее количество, мы теряем часть информации => вывод порциями более правильный.
Так же побочный эффект этого подхода в том, что объединенный массив где-то нужно хранить=> большие расходы на память, если массив здоровенный.
Разница во времени с использованием StringBuilder и без его использования я думаю, что можно объяснить тем, что операция IO сама по себе медленная=> чем реже мы обращаемся к консоли, тем быстрее работает все в целом.

CSS всплывающая кнопка

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

Нужна помощь
.mycls ul { display: inline-block; position: absolute; } .show .mycls a { display: block; float: left; text-align: center; } /* Обертка */ .mycls li { overflow: hidden; position: relative; } .show { position: absolute; left: 0; right: 0; bottom: 0; -webkit-transition: all .2s ease-in-out; -moz-transition: all .2s ease-in-out; -ms-transition: all .2s ease-in-out; -o-transition: all .2s ease-in-out; transition: all .2s ease-in-out; -webkit-transform: translateY(100px); -moz-transform: translateY(100px); -ms-transform: translateY(100px); -o-transform: translateY(100px); transform: translateY(100px); } /* Наведение */ ul:hover .show { -webkit-transform: translateY(0px); -moz-transform: translateY(0px); -ms-transform: translateY(0px); -o-transform: translateY(0px); transform: translateY(0px); position: absolute; } .mycls { width: 220px; height: 310px; float: left; border: 1px solid #808080; border-radius: 5px; padding: 5px; margin: 0px 10px 10px 0px; /*margin between item*/ }



Ответ

Спасибо!
.mycls li { overflow: hidden; position: relative; height: 100%; }

Имеет ли значение порядок “case-ов” в структуре “switch case”?

Я работаю с болшим количеством данных и они проходят через множество switch case операторов.
Есть ли разница в том как расределять case-ы внутри структуры? Будет ли более продуктивным поднять более часто встречаюшиеся случаи на первые строчки? Т.е. разбиваеться ли эта структура внутри на "if else" компоненты?
Работаю на java, но предполагаю что одинаковый подзод будет и в Сишеках.


Ответ

Для таких языков как Си, C++, C# - производительность весьма слабо зависит от количества блоков case и вовсе не зависит от их порядка (все равно компилятор их переупорядочит как ему нужно).
Для языка Java - производительность еще как зависит от порядка блоков, а иногда еще и результат может меняться (если вы используете класс с некорректной реализацией equals). Потому что компилятор Java преобразует оператор switch во что-то вроде серии "if - else if - else if - else"

Подключить svg в элементе через use

Использую такую структуру svg

Подключаю так:

В стилях указываю размер и цвет. Не отображается.
Как правильно подключить svg в элементе через use? И как можно таким способом сделать маркеры списка?


Ответ

Использование
К сожалению, этот способ не работает в IE, даже в 11 версии. Есть скрипт, который обрабатывает соответствующие ссылки для браузеров, где они не работают.
Будьте так-же осторожны: в Сhrome невозможно использовать фильтры на таких элементах. Пропадают и объекты с примененными фильтрами как изнутри так и на сам use элемент. Кроме того пропадают объекты с фильтрами из внешних файлов. Этот баг они не могут решить вот уже 5 лет
Тест:
Если svg во внешнем файле, нужно указать путь к нему:


Использование и стилизация CSS:
.marker use{ fill:red; } Тест:
Использование как inline-изображение в CSS:
Есть более кроссплатформенный метод. Маркеры списка можно делать так:
.arrow { background: url('data:image/svg+xml,%3Csvg%20%20%20xmlns=%22http://www.w3.org/2000/svg%22%20%20%20viewBox=%22-2%20-2%2022%2044%22%20width=%2220%22%20height=%2240%22%3E%3Cpath%20d=%22M%2010,0%200,20%2010,40%22%20style=%22fill:none;fill-rule:evenodd;stroke:#CCCCCC;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1%22%20/%3E%3Cpath%20d=%22M%2020,0%2010,20%2020,40%22%20%20%20%20style=%22fill:none;fill-rule:evenodd;stroke:#CCCCCC;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1%22%20/%3E%3C/svg%3E'); width: 20px; height: 40px; }


SVG закодирован через encodeURI:
console.log(encodeURI(''))
Полученное помещается в CSS таким образом:
background: url('data:image/svg+xml,[код картинки]')

FlipClock с перезагрузкой страницы браузера

Вопрос: Как сделать чтобы отсчет был с определенного момента и при перезагрузки страницы браузера не сбрасывался, а продолжал отсчет?
Использую: FlipClock
Код:
var clock; clock = $('.clock').FlipClock({ //clockFace: 'DailyCounter', autoStart: false, //Отключаем автозапуск countdown: true, //Отсчет назад language:'ru-ru', //Локаль языка callbacks: { stop: function() { $('.message').html('The clock has stopped!') } }, }); clock.setTime(60); //Устанавливаем нужное время в секундах clock.setCountdown(true); //Устанавливаем отсчет назад clock.start(); //Запускаем отсчет



Ответ

Можно при первой загрузке устанавливать текущее время в куки или localStorage и проверять, если куки нет, то время 60, если есть, то 60 минус разница между текщим временем и временем в куках
var clock; clock = $('.clock').FlipClock({ //clockFace: 'DailyCounter', autoStart: false, //Отключаем автозапуск countdown: true, //Отсчет назад language:'ru-ru', //Локаль языка callbacks: { stop: function() { $('.message').html('The clock has stopped!') } }, }); if(!$.cookie('time')){ $.cookie('time', new Date().getTime()); var time = 60; }else{ var time = parseInt(60 - (new Date().getTime() - $.cookie('time'))/1000); if(time < 0){ time = 0; } } //или то же самое с localStorage /* if(!localStorage.getItem("time")){ localStorage.setItem('time', new Date().getTime()); var time = 60; }else{ var time = parseInt(60 - (new Date().getTime() - localStorage.getItem("time"))/1000); if(time < 0){ time = 0; } } */ clock.setTime(time); //Устанавливаем нужное время в секундах clock.setCountdown(true); //Устанавливаем отсчет назад clock.start(); //Запускаем отсчет


Вопрос по указателям в Golang

Недавно начал изучать язык программирования Golang, не очень по началу хотелось, но по работе нужно было, после программирования на Java чуток сложновато. Появилось пару вопросов, в языке Golang простые типы передаются по значению, так же к простому типу относятся и массивы, maps и slices передаются по ссылке, структуры я понял можно передавать как по ссылке так и по значению, все зависит от разработчика, но часто натыкаюсь на примеры в нете где слайсы и мапы передают через взятие адреса, зачем это нужно, если по умолчанию, они все равно так и возвращаются, тем более если передать слайс явно по ссылке то его уже нельзя итерировать, если я что-то не правильно понял объясните, очень мало документации на русском.


Ответ

В golang нет передачи параметров по ссылке - параметры всегда передаются по значению, т.е. копируются. Оператор & - это взятие адреса переменной, т.е. передача указателя, а не передача параметра по ссылке, т.е. как частный случай по значению передаются указатели. map, slice - тоже передаются по значению, просто у них внутри указатели и происходит копирование указателей, а не содержимого таблицы/среза.
Проще всего это продемонстрировать на примере slice (среза). Внутри slice представляет собот структуру: https://github.com/golang/go/blob/master/src/runtime/slice.go
type slice struct { array unsafe.Pointer len int cap int }
т.е. при передаче по значению - можно изменять элементы внутри slice.array, т.к. указатель после копирования будет указывать на ту же область памяти что и исходный, но вот изменить длину или вместимость срезу уже не получится. Точнее эти изменения не будут видны снаружи вызываемой функции, т.к. длина, вместимость и (возможно) указатель array изменятся только в копии среза.
Вот наглядный пример: https://play.golang.org/p/SpFFDdzeXR
package main
import ( "fmt" )
func f_slice_item(s []int) { s[0] = 1 }
func f_slice_size(s []int) { s = append(s, 1) }
func f_slice_pointer_item(s *[]int) { (*s)[0] = 3 }
func f_slice_pointer_size(s *[]int) { *s = append(*s, 5) }
func f_iter(s *[]int) { for i, v := range *s { fmt.Println(i, "-", v) } }
func main() { var s []int
fmt.Println("slice by value") s = []int{0} f_slice_item(s) fmt.Println(s)
s = []int{0} f_slice_size(s) fmt.Println(s)
fmt.Println() fmt.Println("slice by pointer") s = []int{0} f_slice_pointer_item(&s) fmt.Println(s)
s = []int{0} f_slice_pointer_size(&s) fmt.Println(s)
fmt.Println() fmt.Println("iter") f_iter(&s) }
Результат выполнения:
slice by value [1] [0]
slice by pointer [3] [0 5]
iter 0 - 0 1 - 5

Почему метод push() добавляет запятую?

Столкнулась с проблемой следующего рода. Необходимо динамически рендерить с сервера данные...
Данные получаю в таком формате
task={'1': [{'text': 'Задача раз'}, {'date': 'Сегодня'}, {'acept': 'Готово'}], '2': [{'text': 'Задача два'}, {'date': 'Завтра'}, {'acept': 'В процессе'}], }
Для обработки и рендеринга использую следующий код
function getAndRenderTasks(){ $.getJSON("/tasks/api/v1.0/tasks", function (data) { var tasks = [] // Место хранения всех задач $.each( data, function(key, val) { // Перебираем ключи и значения // пришедших в ответе var taskData = [] // Данные одной задачи for (var i = 0; i < val.length; i++) { // хешы задачи $.each(val[i], function(key1, val1){ // достаем данные из хеша taskData.push( "

"+val1+"
") // ложим добытые значения в массив таска }) } tasks.push( "
"+taskData+"
") // добавляем в общий список }) $( "
", { // Рендерим список "class": "my-new-list", html: tasks.join("_______________") }).appendTo( "body") }) }
На выходе получаю следующее
Задача раз , Сегодня , Готово _______________ Задача два , Завтра , В процессе
как убрать запятые? Они мне не нужны...


Ответ

Дело в том, что у вас taskData — массив, а его представление в строке является перечисление значений через запятую.
Пример:
var test = [1,2,3].toString(); console.log(test);
Чтобы их объединить в строку, воспользуйтесь методом join c "пустотой" в качестве разделителя:
taskData.join('')
Всё....

Итог:
task = { '1': [{'text': 'Задача раз'}, {'date': 'Сегодня'}, {'acept': 'Готово'}], '2': [{'text': 'Задача два'}, {'date': 'Завтра'}, {'acept': 'В процессе'}], }; //var tasks = [] // Место хранения всех задач var tasks = []; // Место хранения всех задач $.each(task, function(key, val) { // Перебираем ключи и значения // пришедших в ответе var taskData = []; // Данные одной задачи for (var i = 0; i < val.length; i++) { // хешы задачи $.each(val[i], function(key1, val1) { // достаем данные из хеша taskData.push("

" + val1 + "
"); // ложим добытые значения в массив таска }); } tasks.push("
" + (taskData.join('')) + "
"); // добавляем в общий список }); $("
", { // Рендерим список "class": "my-new-list", html: tasks.join("_______________") }).appendTo("body");

Как изменить HTML в массиве?

Формирую данные с сервера динамически и храню промежуточные данные задачи в массиве примерно в таком виде.

Задача раз
Сегодня
Готово

Код с помощью которого формирую данные
function getAndRenderTasks(){ $.getJSON("/tasks/api/v1.0/tasks", function (data) {
var tasks = [] // Место хранения всех задач
$.each( data, function(key, val) { var taskData = [] // промежуточные данные
for (var i = 0; i < val.length; i++) {
$.each(val[i], function(key1, val1){ taskData.push( "
"+val1+"
") }) }
tasks.push( "
"+taskData.join('')+"

")
})
$( "
", { "class": "my-new-list", html: tasks.join("") }).appendTo( "body") }) }
Проблема в том, что прежде чем отрендерить список задач мне необходимо в некоторые из div задачи, добавить еще данные, типа ссылок, иконок и так далее... как мне сделать это с помощью js что бы получилось что то типа:
$event.details
23:33-23:45


Буду очень благодарна


Ответ

Если я правильно понял задачу, то вот так:
function getAndRenderTasks() { $.getJSON("/tasks/api/v1.0/tasks", function(data) {
var tasks = [] // Место хранения всех задач
$.each(data, function(key, val) { var taskData = [] // промежуточные данные
for (var i = 0; i < val.length; i++) {
$.each(val[i], function(key1, val1) { var $elem = $("

" + val1 + "
");
// Изменяете в элементе что нужно
taskData.push( $elem.get(0).outerHTML ); }) }
var $task = $("
" + taskData.join('') + "

");
// Изменяете в элементе что нужно
tasks.push( $task.get(0).outerHTML );
})
$("
", { "class": "my-new-list", html: tasks.join("") }).appendTo("body") }) }

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

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


Ответ

И что вы хотите получить? Отсутствие объекта? Но если объект начал создаваться - то на выходе должен либо быть корректный объект, либо исключение.
Вы можете, скажем, освободить память - выполняя действия деструктора, но все равно если нет исключения - в результате должен быть создан валидный объект...
Вы в принципе можете вызвать деструктор
class String { public: String(const char * s); ~String(); private: char * s; };
String::String(const char * x) { s = new char[strlen(x)+1]; strcpy(s,x); if (1 /*в строке - маты :)*/) { this->~String(); s = nullptr; } }
String::~String() { delete[] s; }
int main(int argc, const char * argv[]) { String s("hello"); }
Только объект-то все равно будет создан. Как и при динамическом создании - вызвав new, вы уже выделяете память. Если конструктор не сгенерирует исключение - что окажется в этой памяти?

Передача дополнительных переменных в роутер

Доброго!
Не совсем ещё втянулся в прелести Node.JS, потому туплю..
В принципе, тривиальный сервер app.js
router = require('./routes'); // Каталог с роутерами var isDebug = true; // Переменная для примера (которую и хочется передать) var port = 666; var app = express(); app.listen(port, function(){ console.log('SERVER STARTED AT PORT: ' + port); }); router(app, connection, isDebug); // Передали переменую
Далее, в ./routes/index.js
var users = require('./users'); // Куда будем отсылать module.exports = function (app, isDebug) { app.get('/users', users.login); // <-- Вот как именно сюда передать isDebug??? };
Очередным параметром - не хочет, ругается:
Error: Route.get() requires callback functions but got a [object Boolean]
А если далать сразу ./routes/index.js, к примеру, так:
module.exports = function (app, connection, isDebug) { app.get('/users', function (req, res) { if (isDebug) console.log('Trying auth...'); }); };
Всё работает, но так накопится очень много кода в ./routes/index.js, который хотелось бы разделить.. Для примера, ./routes/user.js
var login = function (req, res) { if (isDebug) console.log('Trying auth...'); }; module.exports.login = login;
Всё, естесственно, упрощено. Как бы это поизящнее оформить, посоветуйте, пожалуйста, коллеги?


Ответ

Один из простых вариантов добавления неких дополнительных параметров в обработку запроса - middleware. Например в корневом роутере:
router.use(function (req, res, next) { req.yourVar = "something"; req.isDebug = true; next(); });
или на уровне приложения
app.use(function (req, res, next) { req.yourVar = "something"; req.isDebug = true; next(); });
Дополнительную информацию можно найти здесь

Застревают очереди при отправке писем

Застревают очереди при отправки чере queue, если ставлю просто через send то отрабатывает стабильно
Mail::to($usermail, $username)->send(new \App\Mail\ConfirmEmail
Какие варианты решения этой проблемы существуют. Заранее благодарен. Почтовый сервер exim
Проблема в том, что это задерживает отработку скрипта так как очередь работает прозрачно и на отработку скрипта никак не влияет, а при прямой отправке происходит задержка и довольно существенная так как отправка идет не одному адресату, а десятку или даже сотне
Драйвер Redis


Ответ

При использовании QUEUE_DRIVER=database
Если создана таблица для сбора заданий завершенных с ошибками, там будет содержаться подробная информация. Если не создана таблица выполните
./artisan queue:failed-table ./artisan migrate
Снова запустите listener
./artisan queue:work --queue=<название_очереди> --sleep=2 --tries=1 --timeout 30 --daemon
Выполните отправку сообщения и посмотрите есть ли не выполненные задания
./artisan queue:failed
Если будет такой вывод
+----+------------+-------+-----------------------+--------------------- + | ID | Connection | Queue | Class | Failed At | +----+------------+-------+-----------------------+--------------------- + | 10 | database | email | App\Jobs\SendEmailJob | 2017-04-11 11:43:16 | | 9 | database | email | App\Jobs\SendEmailJob | 2017-04-11 11:40:16 |
выполните SQL запрос, в поле exception будет содержаться информация об ошибке.
SELECT * FROM failed_jobs;

Wireshark разница между двумя фильтрами

Фильтр 1 : !(ip.addr == X.X.X.X) Фильтр 2 : ip.addr != X.X.X.X В обеих фильтрах правое выражение одинаковое. В чем между ними разница? А разница есть, т.к. один и тот же буфер после фильтрации выдает разные результаты. Спасибо.


Ответ

Разница между ними есть. !(ip.addr == X.X.X.X) значит ! (ip.src == X.X.X.X or ip.dst == X.X.X.X), то есть показать весь трафик кроме источника или назначения X.X.X.X. А ip.addr != X.X.X.X значит ip.src != X.X.X.X or ip.dst != X.X.X.X, то есть показать весь трафик кроме источника и назначения X.X.X.X. Подробнее про фильтры можно здесь почитать https://wiki.wireshark.org/DisplayFilters#Examples

swift: Загрузка нескольких файлов

Нужно скачать 10 файлов с показом прогресса загрузки для всех 10 файлов после нажатия на любую ячейку таблицы. Каждой ячейке соответствует свой файл( cell1 - file1, cell2 - file2 и т.д ). Все 10 файлов загружаются нормально. Проблема в том, что прогресс загрузки отображается только в нажатой ячейке для одного файла. А нужно чтобы прогресс отображался во всех ячейка для соответствующих им файлов. Как это сделать?
Этот код использую для загрузки файлов:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
for index in 1...10 { let url = URL(string: "link\(index)")! let downloadTasks = backgroundSession.downloadTask(with: url) downloadTasks.resume()
let progressView = progressViews(frame: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(24), height: CGFloat(24))) let cell = tableView.cellForRow(at: indexPath) cell?.accessoryView = progressViews progressView.startprogressView() }}


Ответ

В принципе у Вас уже всё готово для решения поставленной Вами задачи, Вы лишь забываете правильно указать ячейку, у которой надо показывать загрузку. Кроме этого, самым лучшим вариантом для Вас будет сохранять индексы необходимых ячеек в какую-нибудь переменную, а зачем при перерисовке из неё извлекать значения (если бы у Вас гарантированно все элементы всегда были бы видимы, то можно было бы решить все проблемы проще). Итак, создаёте такое член-данное у себя в классе:
private var cellsIndexesForLoaing = [Int]()
При нажатии на ячейку инициализируйте данную переменную нужным диапазоном:
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.cellsIndexesForLoaing = [Int](0..<10) self.table.reloadData() // И не забудьте обновить саму таблицу }
Затем при перерисовке каждой ячейки проверяйте, надо ли начинать загрузку соответствующего файла:
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = table.dequeueReusableCell(withIdentifier: "Идентификатор Вашей ячейки", for: indexPath) let indexOfCell = self.cellsIndexesForLoaing.index(of: indexPath.row) if (indexOfCell != nil) { // Если текущая ячейка попала в диапазон, то начинаем загрузку
loadFileWithProgress(index: indexPath.row, cell: cell) // Функция для загрузки файлов self.cellsIndexesForLoaing.remove(at: indexOfCell!) // Если мы начали загрузку, то текущую ячейку можно смело удалять из диапазона } else {
//Так как ячейки таблицы кешируются и повторно используются, то Вам нужно ещё и вернуть ячейку к первоначальному состоянию (например, просто удалить её accessoryView, а можете ещё и загрузку прервать) cell.accessoryView = nil } return cell }
Функция для загрузки файла может выглядеть так:
func loadFileWithProgress(index:Int, cell:UITableViewCell) {
let url = URL(string: "link\(index)")! //let downloadTasks = backgroundSession.downloadTask(with: url) //downloadTasks.resume()
let progressView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: 20, height: 20)) //let cell = tableView.cellForRow(at: indexPath) progressView.backgroundColor = UIColor.black cell.accessoryView = progressView //progressView.startprogressView() }
В ней я закомментировал всё лишнее и ради примера устанавливаю в качестве accessoryView обычный чёрный прямоугольник.
Весь код в ответе написан на Swift 3.3.

Чтение VM-свойства за пределами VM

Имеется класс Action, который представляет собой некое действие. Это действие также может содержать коллекцию вложенных действий ChildAction.
public class Action { public Action Parent {get;set;} public ObservableCollection ChildActions {get;set;} }
Класс ProjectVM представляет собой коллекцию действий Action
public class ProjectVM : BaseVM { public ObservableCollection Actions {get;set;} }
В MainVM есть свойство, которое хранит активный проект:
public class MainVM : BaseVM { public ProjectVM SelectedProject{get;set;} }
В интерфейсной части ProjectVM представлен TreeView, а коллекция Actions его элементами, которые можно перетаскивать и вкладывать друг в друга.
Drag&Drop реализован с помощью GongSolutions.Wpf.DragDrop.
Мне нужно знать какой элемент куда был перенесен для формирования истории изменений (Undo/Redo) в каждом ProjectVM
Но как в обработчиках Drag&Drop подцепиться к SelectedProject в рамках MVVM, которые находятся вне всей этой экосистемы и просто цепляются к контролам с помощью attached property?


public class DropHandler : IDropTarget { //... public void Drop(IDropInfo dropInfo) { //Здесь нужно взаимодействие с SelectedProject } }
Можно, конечно, сделать свойство SelectedProject статическим, но что-то мне подсказывает, что это неправильно.
Может быть это вообще неправильный подход?


Ответ

Воспользуйтесь мессенджером для передачи сообщений (читай - инициирование событий) между Вашими VM. В коде обработчика drop - вызываете событие, в нужной Вам модели это событие обрабатываете и сохраняете историю действий. Для этой цели можете воспользоваться event broker. Очень удобное API, позволит Вам обеспечить низкий уровень связности между классами приложения.
public class DropInfoEventArgs : EventArgs { public IDropInfo DropInfo { get; private set; }
public DropInfoEventArgs(IDropInfo dropInfo) { this.DropInfo = dropInfo; } }
public class MainVM { private EventBroker broker; private List dropPublishers;
public MainVM() { this.broker = new EventBroker(); this.dropPublishers = new List();
var dropPublisher = new DropHandler(); this.dropPublishers.Add(dropPublisher);
this.dropPublishers.ForEach(dp => this.broker.Register(dp)); } }
public class DropHandler : IDropTarget { [EventPublication("topic://ProjectVM/HasBeenDropped")] public event EventHandler DroppedEvent;
public void Drop(IDropInfo dropInfo) { DroppedEvent(this, new DropInfoEventArgs(dropInfo)); } }
public class ProjectVM { [EventSubscription("topic://ProjectVM/HasBeenDropped", typeof(OnPublisher))] public void DroppedEvent(object sender, DropInfoEventArgs e) { DropHandler eventSource = sender as DropHandler; IDropInfo info = e.DropInfo; //определяем, относится ли это события к нашему ProjectVM, //если да, то выполняем нужные действия } }

Имитация нажатия Ctrl+A, Ctrl+X, Ctrl+V Python

Здравствуйте. Необходимо сделать имитацию нажатия клавиш Ctrl+A, Ctrl+X и Ctrl+V. Пробовал сделать вот так:
import win32com.client
shell = win32com.client.Dispatch('WScript.Shell') shell.SendKeys('^A') shell.SendKeys('^X') # Кое-какие действия с буфером обмена shell.SendKeys('^V')
Не получается. Причём, комбинации типа '+%', 'A' и т.д. работают прекрасно. Буду премного благодарен за название модуля, от которого стоит отталкиваться. Windows 10/Python 3.6.1


Ответ

Разобрался. Прописывая shell.SendKeys('^A') необходимо использовать НИЖНИЙ РЕГИСТР. То есть: shell.SendKeys('^a'). Тогда сработает.

Регулярное выражение для выбора всех предлогов

Мне в тексте нужно найти все предлоги. Для этого я использую следующее регулярное выражение: (\s+?(?:это|как|так|и|в|над|к|до|не|на|но|за|то|с|ли|а|во|от|со|для|о|же|ну|вы|бы|что|кто|он|она)\s+?)
в строке: Разум дан человеку для того, чтобы он разумно жил, а не для того только, чтобы он понимал, что он неразумно живет
не выбирает в ", а не для " предлог "не" потому, что "а" ограничен пробелами, "не" не выбирается так как его пробел забрала "а"


Ответ

Если необходимо найти данные слова между пробелами либо началом или концом строки, можно воспользоваться блоками просмотра назад (?(?См. демо
Если же любую букву можно найти с помщью \p{L}, то можно сформировать собственный шаблон границы слова:
(?См. демо
Здесь (?

Как изменить цвет скролла?

Как изменить цвет вертикаьного скролла в QScrollBar?


Ответ

Воспользуйтесь стилями Qt (stylesheet), например:
from PyQt5.QtWidgets import *
if __name__ == '__main__': app = QApplication([])
w = QListWidget() w.addItems(['item #{}'.format(_) for _ in range(100)]) w.setStyleSheet(""" QScrollBar:vertical { border: 2px solid grey; background: #32CC99; } """)
w.show()
app.exec()
Выглядит это так:


Если захочется применить стиль на все виджеты, то метод setStyleSheet вызываете у объекта QApplication

Проверка коммита на сервере GitLab Community

Проблема в следующем: Заказчик использует GitLab Community в качестве git сервера. Надо запретить push на сервер коммитов, в которых коментарий не содержит номер таска из джиры (формат например: #JIRA-1234). В какую сторону копать? Заранее спасибо.


Ответ

Нужно использовать git hook, проверяющий сообщение коммита.
Как написать хук post-receive
Полная инструкция с примерами есть в документации git.
Кратко: хук получит на вход строку вроде
ab3c291835832c309 b2fed56890cab348 new-branch
В ней:
Хеш предыдущего коммита Хеш нового коммита Название ветки, которую вы запушили на сервер
Имея хеш нового коммита, вы можете получить его сообщение, чтобы проверить его регулярным выражением.
Если оно соответствует требованиям, хук должен вернуть 0, если нет — 1
Как установить его в GitLab
Для установки хука на сервер GitLab нужны права администратора.
Кратко:
Открыть директорию /var/opt/gitlab/git-data/repositories//.git Создать в ней директорию custom_hooks/ А в ней файл pre-receive (это полное имя, расширение не нужно.) Выдайте этому файлу права на выполнение:
chmod +x /var/opt/gitlab/git-data/repositories//.git/custom_hooks/pre-receive Содержимое этого файла — код на любом интерпретируемом языке (bash, python, ruby...), который есть в системе.
Подробная инструкция по установке в GitLab: https://docs.gitlab.com/ce/administration/custom_hooks.html#setup
Пример хука post-receive
Вот подходящий пример хука (источник). Есть также статья от автора хука, объясняющая его работу.
За проверку коммита отвечает вот эта строка:
match = re.search(r'TICKET-[0-9]{2,5}|#TICKET-[0-9]{2,5}|HOTFIX|FORCE', rev)
Соответственно, вам нужно её поменять так, чтобы вместо TICKET был буквенный код проекта в джире (явно это не JIRA).
Смысл HOTFIX и FORCE в том, что иногда бывают коммиты, не принадлежащие ни к какой задаче. Просто нашли ошибку и быстро исправили. Если не предусмотреть такие «волшебные слова», то придётся заводить по задаче на каждую опечатку в комментариях. Но и злоупотреблять ими тоже не нужно.
Код полностью:
#!/bin/python import sys import re import subprocess
#Format: "oldref newref branch" line = sys.stdin.read() (base, commit, ref) = line.strip().split() new_branch_push = re.match(r'[^1-9]+', base) branch_deleted = re.match(r'[^1-9]+', commit) contains_commit_msg = False if not new_branch_push: revs = base + "..." + commit proc = subprocess.Popen(['git', 'rev-list','--oneline','--first-parent', revs], stdout=subprocess.PIPE) lines = proc.stdout.readlines() if lines: for line in lines: rev = str(line) match = re.search(r'TICKET-[0-9]{2,5}|#TICKET-[0-9]{2,5}|HOTFIX|FORCE', rev) if match is not None: contains_commit_msg = True if contains_commit_msg or new_branch_push or branch_deleted: exit(0) else: print "Commit does not contain the story associated with the commit in the format: TICKET-123 or #TICKET-123" exit(1)

Retrofit асинхронные вызовы

Использую асинхронные вызовы. И у меня возник вопрос. Я использую ProgressDialog. Дело в том что, если один вызов, то он идеально работает. А если я вызываю несколько, то он закрывает после первого. Понятно что благодаря этому коду dialog.dismiss();. Как сделать так, чтоб все запросы привязать к одному ProgressDialog. Если какие фрагменты кода надо, пишите скину.
public void generateYkrepClan(ApiService api, final ProgressDialog dialog, final String id_clan) {
Call call = api.getYkrepClan(id_clan, application_id); call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { dialog.dismiss();
if (response.isSuccessful()) { try { list = response.body().string(); Log.e("EWQ", list); clan_dannie.setYkrep(generateDannieClan.getYkrep(list)); // clan_dannie.setDannieCoklanovzas(generateDannieClan.generatePersonallyDanieClan(list, dannieClanNew)); } catch (IOException e) { e.printStackTrace(); } } else { Snackbar.make(parentView, "kek", Snackbar.LENGTH_LONG).show(); } }
@Override public void onFailure(Call call, Throwable t) { dialog.dismiss(); } });
}


Ответ

Можно воспользоваться RxJava
Api.java
public interface Api { @GET("/api.php") Flowable> getYkrepClan(/**/); }
Простой запрос
Flowable> firstFlowable = api.getYkrepClan(id_clan, application_id);
Два последовательных запроса:
Flowable> flowable = firstFlowable .concatWith(api.anotherRequest());
Два параллельных запроса:
Flowable> flowable = firstFlowable .mergeWith(api.anotherRequest());
Второй запрос на основе результата из первого:
Flowable> flowable = firstFlowable .flatMap(new Function, Flowable>>() { @Override public Flowable> apply(Response response) throws Exception { Log.d("TAG", response.body().string()); return api.anotherRequest(response.body().string()); } })
Выполнить:
flowable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new FlowableSubscriber>() { @Override public void onSubscribe(Subscription s) { //Показать диалог s.request(Long.MAX_VALUE); }
@Override public void onNext(Response responseBodyResponse) { //Прилетел ответ Log.d("TAG",response.body().string()); }
@Override public void onError(Throwable t) { //Ошибка }
@Override public void onComplete() { //Убрать диалог } });

активное меню после перехода на другую страницу

Добрый день. возник такой вопрос. Нужно оставить активными меню, при переходе на новую страницу или просто обновления страницы, которые были открыты.
У меня получилось сделать только для одного меню, которое было выбрано. При переходе на другую страницу я добавляю к URL'у hash (например #Submenu1), затем скриптом считываю его и открываю это подменю при загрузке страницы.
$(document).ready(function () { var x = window.location.hash; var hash = x.hash; $(hash).attr("class", "mainmenu collapse in") });
Я пробую искать меню которые активны, но проблема в том, что сначала выполняется .click, а только потом открывается само меню. В итоге ищется на одно меню меньше.
$('a.bm').click(function () { $n = $('div.mainmenu.collapse.in'); });
Вторая проблема заключается в том, что $('div.mainmenu.collapse.in'); выдаёт результат типа: [div#SubMenu11.mainmenu.collapse.in, prevObject: jQuery.fn.init(1), context: document, selector: "div.mainmenu.collapse.in"] а мне хотелось бы получать только id этого элемента, а не всю строку .
Меню.
int index = 1; var ID = "SubMenu" + index; while (reader.Read()) { if (groupName != reader["GROUPNAME"].ToString()) { if (!string.IsNullOrEmpty(groupName)) { @:

} groupName = reader["GROUPNAME"].ToString(); ID = "SubMenu"+index; @: @groupName  

Django генерация фильра модели

Есть фильтр по полям модели:
queryset = queryset.filter( Q(title__icontains=search_text) | Q(description__icontains=search_text) | Q(name_icontains=search_text) )
Подскажите, как сделать, чтобы блок
Q(title__icontains=search_text) | Q(description__icontains=search_text)| Q(name_icontains=search_text)
Генерировался в зависимости от обстоятельств?
Например, в одном случае нужно, чтобы фильтр был такой:
Q(description__icontains=search_text) | Q(name_icontains=search_text)
В другом такой:
Q(title__icontains=search_text) | Q(description__icontains=search_text) |
Или даже такой:
Q(title__icontains=search_text)
Объекты Q я бы мог сгенерировать при помощи словаря, Например:
search_text = 'somthing text' fields_name = ['title', 'description', 'name']
queries = [ Q(**{field+'__icontains': search_text}) for field in fields_name]
Но как потом это:
[, , ]
Через OR засунуть в filter - не могу никак разобраться. Прошу помощи.


Ответ

query = Q() for q in queries: query |= q
или
import operator query = reduce(operator.or_, queries)