Страницы

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

понедельник, 19 ноября 2018 г.

JavaScript: клик по перекрытому элементу

В данном эксперименте синий квадрат спозиционирован абсолютно, полностью закрывая собой красный. Допустим, по тем или иным причинам красный квадрат также спозиционировать абсолютно и добавить ему больший z-index не позволено. Можно ли при таком раскладе заставить реагировать на клик красный квадрат?
var $redDiv = $('.div1'); var $blueDiv = $('.div2'); var $parent = $('.parent'); $redDiv.on('click', function(){ console.log('OK'); }); .div1, .div2{ width: 100px; height: 100px; } .parent{ position: relative; height: 200px; } .div1{ background: rgba( 255, 0, 0, 0.5); } .div2{ background: rgba( 0, 0, 255, 0.5); position: absolute; top: 0; left: 0; }



Ответ

Используйте pointer-events: none; на том элементе, который должен быть «прозрачным» для кликов.
var $redDiv = $('.redDiv'); var $blueDiv = $('.blueDiv'); var $parent = $('.parent'); $redDiv.on('click', function(){ alert('Click on Red catched'); }); .redDiv, .blueDiv{ width: 100px; height: 100px; } .parent{ position: relative; height: 200px; } .redDiv{ background: red; } .blueDiv{ background: blue; position: absolute; pointer-events: none; top: 10px; left: 10px; }


Как лучше наследовать обычный класс от дженерика в С#

Как написать наследование обычного класса от дженерика или это не совсем правильная практика?
using System;
public class Program{ public static void Main(){
var obj1 = new Child(25); obj1.objectType(); } }
class Child : Parent {
public Child(int num){ this.obj = num; } }
class Parent{ T obj;
public Parent(T obj) { this.obj = obj; }
public void objectType(){ Console.WriteLine("Тип : " + typeof(T)); }
}


Ответ

Наследовать от обобщенного класса можно и такое решение оправдано. Но при этом нужно либо чтобы новый класс тоже был обобщенным, либо указывал конкретный тип параметра.
Т.е. либо:
class Child : Parent { public Child(T num) : base(num) { } }
Либо:
class Child : Parent { public Child(int num) : base(num) { } }
P.S. Как верно заметил @Grundy, нужно вызывать базовый конструктор.

Массив целых чисел: TypeError: only length-1 arrays can be converted to Python scalars

import scipy import scipy.fftpack import cmath import math import matplotlib.pyplot as plt import numpy as np from scipy import signal from scipy.signal import freqs, iirfilter xx = np.linspace(0, 1024, 1024) # диапазон значений x byts = ([0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1]) ff = 64 # %Частота несущей ns = np.sin(2 * np.pi * (x - 1) * ff / 1024) # несущая y = ns * byts[round(int(x + 31) / 64)] # %сигнал plt.plot(y)
Ошибка:
TypeError: only length-1 arrays can be converted to Python scalars
Как правильно нужно задать массив целых чисел х, чтобы не возникало данной ошибки?


Ответ

Разберёмся, почему возникает данная ошибка. Посмотрим на выражение:
round(int(x + 31) / 64)
x + 31 это массив длины 1024, а мы его приводим к int'у и непонятно, что должно получиться в результате. Python так и говорит:
TypeError: только массивы длины один могут быть приведены к скалярному типу (int это скалярный тип)
Уберём приведение к int'у:
y = ns * byts[round((x + 31) / 64)]
Ошибка пропадёт, но появится другая:
TypeError: type numpy.ndarray doesn't define __round__ method
Можно заменить round на np.round
y = ns * byts[np.round((x + 31) / 64)]
Мы получим другую ошибку
TypeError: only integer scalar arrays can be converted to a scalar index
Дело в том, что np.round((x + 31) / 64) это массив, с типом элементов float, а мы используем этот массив как массив индексов, а индексы могут быть только целыми. Нужно изменить тип элементов массива с помощью astype
y = ns * byts[np.round((x + 31) / 64).astype(int)]
Мы опять получим другую ошибку
TypeError: only integer scalar arrays can be converted to a scalar index
Дело в том, что byts это обычный массив, и через квадратные скобки нельзя обращаться с массивом индексов. Сделаем byts numpy-массивом:
byts = np.array([0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1])
Наша следующая ошибка
IndexError: index 16 is out of bounds for axis 1 with size 16
Возникает из-за того, что в конце массива np.round((x + 31) / 64 есть элементы, равные 16. Возможным решением будет изменение типа элементов массива x на int
x = np.linspace(0, 1023, 1024).astype(int)
и замена сложного выражения np.round((x + 31) / 64 на простое x // 64
y = ns * byts[x // 64] # %сигнал
Итоговый код:
import scipy import scipy.fftpack import cmath import math import matplotlib.pyplot as plt import numpy as np from scipy import signal from scipy.signal import freqs, iirfilter x = np.linspace(0, 1023, 1024).astype(int) # диапазон значений x byts = np.array([0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1]) ff = 64 # %Частота несущей ns = np.sin(2 * np.pi * (x - 1) * ff / 1024) # несущая y = ns * byts[x // 64] # %сигнал plt.plot(y)

Геттеры и сеттеры для статических полей

Вопрос, возможно, глупый, но всё же... Нужны ли геттеры и сеттеры для статических полей, или их лучше объявлять public?
Т.е, какой из вариантов лучше?
1 вариант:
public abstract class SomeClass { public static boolean isReadOnly = false; }
и далее использовать SomeClass.isReadOnly = true;
2 вариант:
public abstract class SomeClass { private static boolean isReadOnly = false;
public static boolean isReadOnly() { return isReadOnly; }
public static void setReadOnly(boolean isReadOnly) { SomeClass.isReadOnly = isReadOnly; } }
и далее использовать SomeClass.setReadOnly(true);


Ответ

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

Некорректный шрифт при загрузке из файла в WPF

Загружаю шрифт в программу посредством
GetNonCachedFontFamilies(MainPath).FirstOrDefault();
Метод GetNonCachedFontFamilies
public static IEnumerable GetNonCachedFontFamilies(string location) { if (string.IsNullOrEmpty("location")) throw new ArgumentException("Must provide a location", "location");
DirectoryInfo directoryInfo = new DirectoryInfo(location); if (directoryInfo.Exists) { FileInfo[] fileInfos = directoryInfo.GetFiles("*.?tf"); foreach (FileInfo fileInfo in fileInfos) yield return CreateFontFamily(fileInfo.FullName); } else { FileInfo fileInfo = new FileInfo(location); if (fileInfo.Exists) yield return CreateFontFamily(location); } }
Метод CreateFontFamily
private static FontFamily CreateFontFamily(string path) { if (!Uri.TryCreate(path, UriKind.Absolute, out Uri uri)) throw new ArgumentException("Must provide a valid location", "path");
return new FontFamily(uri, string.Empty); }
Шрифт программа находит и загружает, с этим проблем нет. Только отображается шрифт не правильно. Это должен быть рукописный кириллический шрифт, а похож на Microsoft Sans Serif/Calibri (т.е. не рукописный). Что я не так делаю? Если что, текст отображаю посредством TextBlock, который динамически создаётся из кода. Прошу без xaml.


Ответ

Вы неправильно используете функцию new FontFamily(uri, string.Empty), надо обязательно использовать имя шрифта. Ниже рабочий код.
public static IEnumerable GetNonCachedFontFamilies(string location) { if (string.IsNullOrEmpty("location")) throw new ArgumentException("Must provide a location", "location");
DirectoryInfo directoryInfo = new DirectoryInfo(location); if (directoryInfo.Exists) { FileInfo[] fileInfos = directoryInfo.GetFiles("*.?tf"); foreach (FileInfo fileInfo in fileInfos) yield return CreateFontFamily(fileInfo.DirectoryName, fileInfo.Name); } else { FileInfo fileInfo = new FileInfo(location); if (fileInfo.Exists) yield return CreateFontFamily(fileInfo.DirectoryName, fileInfo.Name); } }
private static FontFamily CreateFontFamily(string path, string filename) { if (!Uri.TryCreate(path + "\\" + filename, UriKind.Absolute, out Uri uri)) throw new ArgumentException("Must provide a valid location", "path");
GlyphTypeface glyphTypeface = new GlyphTypeface(uri); return new FontFamily(path + "\\#" + glyphTypeface.FamilyNames.FirstOrDefault().Value); }

Можно/нужно ли делать сервисы бизнес логики одиночками (Singleton) или статическими?

Например у меня есть сервисы ScannerService и UsersService. Первый отвечает за управление сканером на устройстве, второй получает данные из базы данных и содержит в себе объект DbContext (реализация UoW) для работы с базой данных. На разных формах используются разные сервисы, но эти два почти на всех. Стоит ли создавать новые объекта в каждой форме, или лучше использовать Singleton?
Можно ли объект, реализующий Unit of work, делать Singleton? Он вроде должен быть уничтожен после выполнения работы сервиса, в котором используется, но для меня не очевидно зачем его создавать по сто раз для каждого сервиса, если можно создать один раз и уничтожить после выполнения работы приложения.
Есть ли причины не делать сервисы статическими, если мне не нужно создавать их объекты, а нужно лишь использовать их функции, которые можно сделать статическими?


Ответ

Объект DbContext кэширует в себе все выбранные через него объекты (т.е. реализует не только Repository, UoW, но еще и Identity Map).
Соответственно, если вы косвенно сделаете его синглтоном, то ваше приложение
закэширует в себе все выбираемые через себя данные (всю базу) перестанет видеть изменения, вносимые в базу извне не сможет восстановиться после первой же ошибки валидации / сохранения (упал один SaveChanges - упадут и все следующие) будет дико тупить при сохранении из-за необходимости обнаруживать изменения в большом количестве объектов
Нет никаких причин делать сервисы или вообще любые другие классы статическими, если того явно не требует логика работы конкретных классов. Т.е. статическим синглтоном может быть какой-то глобальный кэш, который по определению должен быть один на один инстанс приложения. Или, например, класс, оборачивающий в себе доступ к стороннему сервису, и управляющий соединениями к нему (пул соединений SQL, мультиплексор StackExchange Redis и т.п.). И даже в этом случае единственность экземпляра должен обеспечивать контейнер, а не прямая статика.
Все остальное должно быть нестатическим, или, по крайней мере, не должно предполагать статичности/единственности зависимостей в своем коде.

Корутины выполняются в одном потоке?

Короткий вопрос по asincio: Корутины выполняются в одном потоке?
Всегда разные треды, всегда один тред или потоки выделяются по необходимости? Зависит ли это от реализации loop?
Этот вопрос связан с использованием threading.local


Ответ

Да.
An event loop runs in a thread and executes all callbacks and tasks in the same thread.
asyncio.get_event_loop() возвращает цикл событий соответствующий текущему контексту. По умолчанию это текущий поток, то есть один цикл на поток. При вызове из coroutine, возвращается цикл, который эту coroutine выполняет
When called from a coroutine or a callback (e.g. scheduled with call_soon or similar API), this function will always return the running event loop.
Большинство методов и классов в asyncio не являются потокобезопасными. Если хотите из другого потока запустить задачу в цикле, то можно использовать asyncio.run_coroutine_threadsafe()
Даже в одном потоке могут быть проблемы с изменением нелокального состояния при возвращении контроля циклу событий (await). См., PEP 550 -- Execution Context. В Питоне 3.7 доступен contextvars модуль, реализующий PEP 567 -- Context Variables