Страницы

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

понедельник, 18 марта 2019 г.

DbSet.Add() vs DbSet.AddAsync()

Есть отличная статья-ответ, которую наверное можно как некий справочник использовать когда необходимо освежить некоторые моменты в понимании параллельных вычислений. В этой статье касаемо асинхронного программирования, говорится
Асинхронность (asynchrony) подразумевает, что операция может быть выполнена кем-то на стороне...
и исходя из этого я могу понять разницу между DbSet.Save() и DbSet.SaveAsync(), а именно: когда сохранение у нас происходит во внешний источник (к примеру, база данных), где необходимо ожидать ответ и время этого ожидания не зависит от нашего кода, то предпочтительнее использовать асинхронный вариант этого метода, чтобы отпустить поток на другие нужды, а потом когда придет ответ продолжить работу с ответом уже этим или другим потоком.
А что на счет асинхронного варианта AddAsync(), зачем-то он нужен, зачем ожидать ответ, разве добавление не происходит в памяти или я какой-то частный случай не знаю?


Ответ

Согласно докам
This method is async only to allow special value generators, such as the one used by 'Microsoft.EntityFrameworkCore.Metadata.SqlServerValueGenerationStrategy.SequenceHiLo', to access the database asynchronously. For all other cases the non async method should be used.

Не собирается второе издание книги “Язык программирования Rust”

В сеть выложили второе издание популярной книги “Язык программирования Rust” (https://github.com/ruRust/rust_book_2ed). Там же и инструкция, как собрать книжку из заготовок, с помощью mdbook build. Однако - не получается! При выполнении этой команды вадаются сообщения:
(mdbook::utils): Error: Summary parsing failed (mdbook::utils): Caused By: There was an error parsing the numbered chapters (mdbook::utils): Caused By: Error at line 127, column 31: You can't have an empty link.
Я полный профан в Rust, для того и книжку пытаюсь получить - что бы прочитать. Может мне кто-то подсказать, в чём тут проблема?
Да, при первом запуске mdbook build выдалось длинное сообщение про то, что файл book.toml старого формата и его необходимо подправить. Я исправил, в соответствии с рекомендациями. Получилось вот так:
[book] title = "The Rust Programming Language" author = "Steve Klabnik and Carol Nichols, with Contributions from the Rust Community"
[build] [build-dir] destination = './build'


Ответ

Действительно не собирается. Но вопрос можно решить. Не собирается потому, что в файле src/SUMMARY.md не прописано несколько линков. Поступаем следующим образом:
В каталоге src создаем файл dummy.md примерного содержания
## Это файл-заглушка В документации не хватало пару файлов и книга не собиралась. Для этого делаем файл-заглушку.
В файле src/SUMMARY.md в самом конце прописываем линки на этот файл
... - [Appendix](appendix-00.md) - [A - Keywords](appendix-01-keywords.md) - [B - Operators](appendix-02-operators.md) - [C - Derivable Traits](dummy.md) - [D - Nightly Rust](dummy.md) - [E - Macros](dummy.md) - [F - Translations](dummy.md) - [G - Newest Features](appendix-07-newest-features.md)
Все, после этого сборка проходит нормально.

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

Возможен ли способ выяснить - был ли проимпортирован класс\атрибут\функция из текущего файла в другом файле текущего проекта? Например, есть код:
file01.py class Foo1(): pass
class Foo2(): pass
file02.py import file01 class Bar1(): f1 = file01.Foo1() f2 = file01.Foo2()
class Bar2(): pass
Для задачи есть функция:
def inspection(module): for i in dir(module): print('class {0} used in {1}'.format(class_name, module_name))
Что при выполнении: inspection(file01) Выдаст результат типа:
class Foo1 used in: file02 class Foo2 used in: None
Подобный функционал был бы полезен для написания docstring для файлов __init__.py. В котором, согласно PEP257, необходимо отобразить экспортироемую пакетом информацию.


Ответ

К сожелению без запуска кода никак
import sys
def watch_uses(cls, log): class MetaTemp(type(cls)): def __call__(cls, *args, **kwargs): call_frame = sys._getframe(1) log.append('{}:{}'.format( call_frame.f_locals['__file__'], call_frame.f_lineno )) return super().__call__(*args, **kwargs)
class new_cls(cls, metaclass=MetaTemp): pass
return new_cls
class C: pass
uses_C = [] C = watch_uses(C, uses_C)
#здесь вам нужно как-то происпользовать C c = C() c = C()
print(uses_C) #может вывести: ['./t.py:27', './t.py:28']

Repeat mode для фигуры для фона

Делаю разделитель divider, фоном которого должны быть простые кружочки. Если этот фон делаю через Bitmap, то в нем выставляю tileMode=Repeat и работает как надо, но т.к это кружочек из картинки файла, то выглядит он нечетко.

Ввиду этого решил сделать кружок векторным:



Но Bitmap не принимает в качестве источника такую фигуру, а кроме как у Bitmap я больше нигде не нашел tileMode=Repeat, а без этого режима один такой кружок-фигуру растягивает на всю длину разделителя. Подскажите, как это осуществить с фигурой?


Ответ

Kotlin:
class DotsDivider : View {
private val numberOfCircles = 20f private val paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
init { paint.color = Color.LTGRAY paint.style = Paint.Style.STROKE paint.strokeCap = Paint.Cap.ROUND }
constructor(context: Context) : super(context) constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
override fun onDraw(canvas: Canvas) { super.onDraw(canvas)
val width = canvas.width paint.strokeWidth = canvas.height/2f paint.pathEffect = getDashPathEffect(width) canvas.drawLine(width/numberOfCircles/2f, canvas.height/2f, canvas.width.toFloat(), canvas.height/2f, paint) }
private fun getDashPathEffect(width: Int): DashPathEffect{ return DashPathEffect(floatArrayOf(0f, width/numberOfCircles), width/numberOfCircles*2) } }
Java:
public class DotsDivider extends View {
private final float numberOfCircles = 20f; private final Paint paint;
{ paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.LTGRAY); paint.setStyle(Paint.Style.STROKE); paint.setStrokeCap(Paint.Cap.ROUND); }
public DotsDividerJava(Context context) { super(context); }
public DotsDividerJava(Context context, @Nullable AttributeSet attrs) { super(context, attrs); }
public DotsDividerJava(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas);
int width = canvas.getWidth(); paint.setStrokeWidth(canvas.getHeight() / 2); paint.setPathEffect(getDashPathEffect(width)); canvas.drawLine( width/numberOfCircles / 2f, canvas.getHeight() / 2f, canvas.getWidth(), canvas.getHeight() / 2f, paint); } private DashPathEffect getDashPathEffect(int width){ return new DashPathEffect(new float[]{0f, width/numberOfCircles}, width/numberOfCircles*2); } }
в xml

В итоге:
Ps: этот пример можно улучшить, можно создать свои reference для новых атрибутов, цвета, кол-ва или изменить логику.

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

Как увеличить расстояние между буквами и сделать еще менее жирным текст?
Font font = new Font("Courier New", 10, FontStyle.Regular); SolidBrush brush = new SolidBrush(Color.Black); graf.DrawString("Надпись", font, brush, 130, 16);


Ответ

Скорее всего, объект Graphics был получен из класса изображения. Что-то вроде:
var img = new Bitmap(...); graf = Graphics.FromImage(img);
При этом у него заданы определённые значения свойств, которые приводят к рендерингу текста жирным и на вид слипшимся.
Задайте свойство:
graf.TextRenderingHint = TextRenderingHint.AntiAlias;
Попробуйте разные значения.

Двусмысленность при передаче делегата в конструктор

Имеется класс команды, в упрощенном виде выглядящий так :
public class Command {
public Command(int price, Action method) { method.Invoke(); } public Command(int price, Func method) { var id = method.Invoke(); } }
В конструкторе 1 принимающий int и Action - ссылку на метод который ничего не возвращает. В конструкторе 2 Func - ссылку на метод который возвращает целое число. Так же у меня есть 2 метода, котрые могут передаваться в конструктор :
public void toDosome() {
} public int newId() { return 100500; }
Далее я создаю обьект и проблем не возникает :
var command = new Command(11, newId);
Однако если вместо newId окажется toDosome :
var commandTo = new Command(1211, toDosome);
Мне выпадет исключение :
The call is ambiguous between the following methods or properties.
При этом я не могу удалить какой либо конструктор, что бы успешно создавать command или commandTo. Как поступить в такой ситуации ?


Ответ

Создавайте явно делегат типа Action, передавая целевую функцию делегату и проблема выбора перегрузки функции исчезнет
var commandTo = new Command(1211, new Action(toDosome));

Оценка выстрела по мишени (Java, Android)

Пытаюсь реализовать оценку выстрела по мишени. Мишень вот такого типа:
Она прописана в ImageView с прописанным свойством fitCenter в scaleType. Т.е. будет растягиваться под ширину экрана, находясь строго в центре, границами мишени буквально упираясь в границы экрана.
Пользователь касанием устанавливает и перемещает пробоину на мишени, после чего нажатием кнопки "Сохранить" вносит данные и оценку в что-то-типа-БД (SharedPreferences)
Сейчас у меня на оценке висит вот такой код:
public void getTheMarkForShot(float absoluteX, float absoluteY){ ImageView aimTarget = findViewById(R.id.aimTarget); TextView textView = findViewById(R.id.textView2); ImageView red_dot = findViewById(R.id.red_dot); //Координаты центра - считаются правильно float centerX=aimTarget.getX() + aimTarget.getWidth() / 2; float centerY=aimTarget.getY() + aimTarget.getHeight() / 2; //Определим расстояние от центра пробоины до центра мишени double absoluteDistance = Math.sqrt(Math.pow(absoluteX - centerX, 2) + Math.pow(absoluteY - centerY, 2)); //Определяем координаты точки на пробоине, ближайшей к центру мишени double betterX = absoluteX * ((absoluteDistance - (red_dot.getWidth() / 2)) / absoluteDistance); double betterY = absoluteY * ((absoluteDistance - (red_dot.getHeight() / 2)) / absoluteDistance); //Определение оценки и вывод результата byte finalMark; //Если координаты ближайшей точки находятся вне круга (смотрим по его радиусу) if ((Math.pow(betterX - centerX, 2) + Math.pow(betterY - centerY, 2)) > Math.pow(aimTarget.getWidth() / 2 , 2)){ //Оценка равна 0. Выводим результаты на экран. finalMark = 0; String coordinatesMessage = String.format("Координаты выстрела: (%.2f, %.2f). Оценка: %s", absoluteX - centerX, centerY - absoluteY, finalMark); textView.setText(coordinatesMessage); } //Иначе - определяем в каком из сегментов круга находится пробоина else { //Разделим ширину круга на части for (int i = 10; i > -1; i--) { if ((Math.pow(betterX - centerX, 2) + Math.pow(betterY - centerY, 2)) <= Math.pow(aimTarget.getWidth() / 2 - (i * (aimTarget.getWidth() / 2/10)), 2)){ finalMark = (byte)i; String coordinatesMessage = String.format("Координаты выстрела: (%.2f, %.2f). Оценка: %s", absoluteX - centerX, centerY - absoluteY, finalMark); break; } } } }
На касание на данный момент прописано следующее:
@SuppressLint("ClickableViewAccessibility") public void getTouchCoordinates(){ final ImageView aimTarget = findViewById(R.id.aimTarget); final ImageView red_dot = findViewById(R.id.red_dot);
aimTarget.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { float x; float y; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { break; } case MotionEvent.ACTION_MOVE: { x = event.getX(); y = event.getY(); red_dot(x, y); getTheMarkForShot(x,y); return true; } case MotionEvent.ACTION_UP: { x = event.getX(); y = event.getY(); red_dot(x, y); getTheMarkForShot(x,y); return false; } } return true; } }); }
Результат вышеописанного - определяется только оценка 0. В остальных случаях определяются только координаты, без оценки (реализовал в функции red_dot).
Итак, сам вопрос: как в данном случае можно наиболее корректно определить оценку выстрела? Три страницы гугла трижды в день на протяжении трёх дней выдали единственное схожее задание: Задачка по C++ про мишени. Пытался реализовать, в итоге оценка 0 определяется вообще по всему экрану.
Очень прошу помочь, время не то что поджимает - его вообще нет =(


Ответ

Ты все емного усложнил. Все чо тебе надо было, это найти центр круга, он у тебя есть, найти радиус круга, у тебя половина от ширины экрана, расстояние от центра до точки нажатия, тоже считаешь. И надо только проверить как близко точка находится от центра относительно радиуса. Если больше радиуса - 0, в остальном расстояние/радиус и будет от 0 до 1. Инвертироваь еще, отнять это число от 1, чтобы в центре было большее значени. Умнож на 10 и округли и будет число в которое попал