Страницы

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

вторник, 7 мая 2019 г.

Как лучше всего рассчитывать прогресс выполнения и задавать его цену?

Есть некая операция, которое состоит из последовательности действий.
void MyOperation { Action1(); Action2(); Action3(); }
Потребовалось повесить на это просмотр текущего прогресса. Причем на случай изменения действий (добавления, удаления, изменения цены действия), управление прогрессом не должно быть сложным и требовать пересчеты на калькуляторе.
void MyOperation { [CostAttribute(30)] Action1(); [CostAttribute(40)] Action2(); [CostAttribute(30)] Action3(); }
А в самих функциях должен посчитаться общий прогресс (30 + 40 + 30) и текущий для действия (общий/текущий).
То есть если программист добавляет новое действие (Action4), он примерно оценивает, сколько оно будет выполняться и выставляет свою цену, например 100, не меняя остальные цены и соотношения.
Как такое можно сделать?
UPD:
Сначала мне пришло в голову сделать так. Поставить атрибут с ценой над каждым определением действия. Но действие может иметь разную цену в зависимости от контекста. Например, действие копирует файлы. В этом случае оно может использоваться в операции несколько раз, и цена его будет разная. Программист примерно представляет, сколько файлов имеется для копирования, а потому в одном случае это действие будет стоить 10 (примерно 1000 файлов), а в другом - 20 (примерно 2000 файлов). Короче не знаю как это сделать красивее и удобнее в понимании и программировании.


Ответ

Как вариант, можно обернуть MyOperation и Action в классы. В этом случае MyOperation хранит набор Action и выполняет их поочередно. После выполнения действия можно пересчитать прогресс выполнения, используя параметр action.Weight (он же цена).
public class MyOperation { List actions=new List()
public void Run() { foreach(var action in actions) { action.Execute(); this.ResearchProgress(action.weight); } } }

Анимация Transform в ControlTemplate

Как анимировать ScaleTransform кнопки в шаблоне, и какой тип анимации необходимо применить?


Ответ

Вам нужно анимировать не всю трансформацию, а свойства ScaleX и ScaleY этой трансформации. Так как тип этих свойств double, соответственно, нужно использовать DoubleAnimation

Передать два значение в Ajax на сервер

Есть Ajax который должен передавать два значения. Сделал только со одним.
$.ajax({ type: 'POST', url: "/ajax/search_bid_country", data: "city_from="+city_from, success: function(answer) { $(".result_article").empty(); $(".result_article").append(answer); $(".result_article").fadeIn(); $(".load").css({display:"none"}); } });
Но вот второй не могу передать пишит ошибку,
data: "city_from="+city_from, "city_whre="+city_where,
Как быть


Ответ

все просто
data: "city_from=" + city_from + "&city_whre=" + city_where,
теперь должно сработать

Крестики нолики

Пытаюсь реализовать своими силами игру крестики-нолики на Java. Все вроде работает так как задумывалось, но продолжение игры вообще не идет.
Суть в том что метод Exit() зацикливается. при вводе "n" все работает хорошо, а при вводе "Y" Спрашивает по новой.
Подскажите,пожалуйста, в чем ошибка.

package tic_tac_toe;
import java.util.Scanner;
public class XO {
public static void Game(){
Scanner in = new Scanner(System.in); // Подключение класса считывания инф-и (аля Read) String hole; // переменная местоположения
String[][] field = new String[3][3]; // Заполняем массив пробелами, для последущего замещения их Х или О for (int i = 0; i < 3; i++){ System.out.println(); for (int j = 0; j < 3; j++){ field[i][j] = (" [ ] "); System.out.print(field[i][j]); } }
int i = 2; int quit=0; while((i<11) & (quit == 0)){
if (i % 2 == 0){ System.out.println("
Ходит Х"); } else{ System.out.println("
Ходит О"); } System.out.print("Введите клетку:> "); // Считывание ввода, и ход. switch (hole = in.next()){ case "7":{ if (field[0][0] == (" [ ] ")){ if (i % 2 == 0){ field[0][0] = (" [X] "); i++; break; } else { field[0][0] = (" [O] "); i++; break; } } else{ System.out.println("Эта клетка занята, введите другую."); break; } }
case "8":{ if (field[0][1] == (" [ ] ")){ if (i % 2 == 0){ field[0][1] = (" [X] "); i++; break; } else { field[0][1] = (" [O] "); i++; break; } } else{ System.out.println("Эта клетка занята, введите другую."); break; } } case "9":{ if (field[0][2] == (" [ ] ")){ if (i % 2 == 0){ field[0][2] = (" [X] "); i++; break; } else { field[0][2] = (" [O] "); i++; break; } } else{ System.out.println("Эта клетка занята, введите другую."); break; } } case "4":{ if (field[1][0] == (" [ ] ")){ if (i % 2 == 0){ field[1][0] = (" [X] "); i++; break; } else { field[1][0] = (" [O] "); i++; break; } } else{ System.out.println("Эта клетка занята, введите другую."); break; } } case "5":{ if (field[1][1] == (" [ ] ")){ if (i % 2 == 0){ field[1][1] = (" [X] "); i++; break; } else { field[1][1] = (" [O] "); i++; break; } } else{ System.out.println("Эта клетка занята, введите другую."); break; } } case "6":{ if (field[1][2] == (" [ ] ")){ if (i % 2 == 0){ field[1][2] = (" [X] "); i++; break; } else { field[1][2] = (" [O] "); i++; break; } } else{ System.out.println("Эта клетка занята, введите другую."); break; } } case "1":{ if (field[2][0] == (" [ ] ")){ if (i % 2 == 0){ field[2][0] = (" [X] "); i++; break; } else { field[2][0] = (" [O] "); i++; break; } } else{ System.out.println("Эта клетка занята, введите другую."); break; } } case "2":{ if (field[2][1] == (" [ ] ")){ if (i % 2 == 0){ field[2][1] = (" [X] "); i++; break; } else { field[2][1] = (" [O] "); i++; break; } } else{ System.out.println("Эта клетка занята, введите другую."); break; } } case "3":{ if (field[2][2] == (" [ ] ")){ if (i % 2 == 0){ field[2][2] = (" [X] "); i++; break; } else { field[2][2] = (" [O] "); i++; break; } } else{ System.out.println("Эта клетка занята, введите другую."); break; } } default: System.out.println("
Ошибка ведите еще раз!"); break; } // Вывод поля на экран for (int p = 0; p < 3; p++){ System.out.println(); for (int l = 0; l < 3; l++){ System.out.print(field[p][l]); } } for (int t = 0; t<3 ; t++){ // Проверка прямых if (((field[t][0]) == " [O] " & (field[t][1]) == " [O] " & field[t][2] == " [O] ") || ((field[0][t]) == " [O] " & (field[1][t]) == " [O] " & field[2][t] == " [O] ")) { System.out.print("
Победил О "); quit++; Exit(); } else if (((field[t][0]) == " [X] " & (field[t][1]) == " [X] " & field[t][2] == " [X] ") || ((field[0][t]) == " [X] " & (field[1][t]) == " [X] " & field[2][t] == " [X] ")) { System.out.print("
Победил Х "); quit++; Exit(); } else {} } // Проверка диагоналей if (((field[0][0]) == " [X] " & (field[1][1]) == " [X] " & field[2][2] == " [X] ") || ((field[0][2]) == " [X] " & (field[1][1]) == " [X] " & field[2][0] == " [X] ")) { System.out.print("
Победил Х "); quit++; Exit(); } else if (((field[0][0]) == " [O] " & (field[1][1]) == " [O] " & field[2][2] == " [O] ") || ((field[0][2]) == " [O] " & (field[1][1]) == " [O] " & field[2][0] == " [O] ")) { System.out.print("
Победил О "); quit++; Exit(); } else {} } System.out.println(); } public static void Exit(){ // Отсутствует продолжение игры Scanner ex = new Scanner(System.in); String re; do { System.out.print("Хотите продолжить игру? "); re = ex.next(); if (re == "Y"){ Game(); } else if(re == "n") { break; } } while (re == ("Y") || re == "n"); } public static void main(String[] args) { Game(); //Exit(); } }


Ответ

Строки сравнивают методом equals(String str) То есть у Вас должно быть:
do { System.out.print("Хотите продолжить игру? "); re = ex.next(); if (re.equals("Y")) { Game(); } else if (re.equals("N")) { break; } } while (re.equals("N") || re.equals("Y"));
А при вводе "n" поток выходит из цикла лишь потому, что Вы воспользовались досрочным выходом break из цикла.

Binding color to constants class

Не могу прибиндить цветовую константу, которая находится в другой dll-ке.
"/>
Студия ругается на плохой код и не хочет ничего делать. И принимает только объект, а стринг не хочет. Как я понял, нужен конвертер.
Есть ли стандартный, или самому писать? (если можно, пример).


Ответ

Ссылки на статические свойства нужно давать не через Binding, а через x:Static

При этом у вас, разумеется, должно быть правильно объявлено пространство имён constants, что-то вроде
xmlns:constants="clr-namespace:Namespace.In.Assembly;assembly=Your.Assembly.Name"
Не забудьте убедиться, что ваша сборка с константами называется Your.Assembly.Name, в ней в пространстве имён Namespace.In.Assembly находится public-класс ColorConstants, у которого есть статическое свойство (а не поле!) Black, у которого хотя бы getter объявлен как public

Для случая, когда ваш x:Static обладает неправильным типом (у вас строка, а ожидается Color), вам нужно применить конвертер. Самый простой синтаксически способ — написать свой MarkupExtension в замену x:Static, который заодно конвертировал бы значение в нужный тип стандартным конвертером.
Итак:
public class SmartStaticExtension : StaticExtension { public SmartStaticExtension(string member) : base(member) { }
public override object ProvideValue(IServiceProvider serviceProvider) { // получим значение стандартного x:Static object value = base.ProvideValue(serviceProvider);
// попытаемся вычислить тип, к которому надо привести IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget; if (target != null) { Type targetType = typeof(object); // если целевое свойство - DependencyProperty DependencyProperty dp = target.TargetProperty as DependencyProperty; if (dp != null) { targetType = dp.PropertyType; // берём тип у него } else { // целевое свойство - обыкновенное свойство, используем рефлексию PropertyInfo pi = target.TargetProperty as PropertyInfo; if (pi != null) targetType = pi.PropertyType; }
// получаем стандартный конвертер: TypeConverter converter = TypeDescriptor.GetConverter(targetType); // и конвертируем value = converter.ConvertFrom(value); }
return value; } }
Имея такой конвертер, можно написать

(разумеется, пространство имён local должно указывать туда, где определён SmartStaticExtension).
Работает как со строками ("LightCyan") так и с RGB-константами ("#708090").

Как посмотреть размер раздела на диске?

Допустим у меня есть диск sda. Мне нужно посмотреть занимаемый размер на sda6.
Есть команда df -h, но она показывает всю информацию по дискам, а мне нужен только раздел sda6 на диске sda.


Ответ

если раздел примонтирован, то можно посмотреть его размер, указав путь к нему:
$ df /dev/sda6
если же раздел не примонтирован, программа df бессильна, и можно посмотреть лишь информацию о всех разделах данного блочного устройства. пара вариантов:
$ sudo fdisk -l /dev/sda $ sudo parted /dev/sda print all

Аргументы методов в C# по ссылке или по значению?

Насколько я знаю в сишарпе аргументы передаются по значению. Но тогда я не понимаю вот чего. Я сейчас смотрю код, в котором присутствует такой метод:
public static string GetRequest(string Url, string UserAgent = "", CookieDictionary Cookies = null, ProxyType ProxyProto = ProxyType.None, string ProxyString = "") { ...
try { HttpResponse response = request.Get(Url); Cookies = response.Cookies; response_html = response.ToString(); }
}
То есть он получает куки, а потом добавляет в них те что получены из ответа. Если переменные передаются по значению то так по-идее работать не должно, но я проверил вот так:
CookieDictionary cookies = new CookieDictionary(); string url = "http://mail.ru"; string resp = Web.GetRequest(url, "", cookies, Web.ProxyType.HTTP, "127.0.0.1:8888"); resp = Web.GetRequest(url, "", cookies, Web.ProxyType.HTTP, "127.0.0.1:8888");
При втором запросе передаются куки, которые получены при первом. Кроме того в методе я пробовал добавлять свои куки через Cookies.Add() и они присутствовали в следующих вопросах. Почему это работает?


Ответ

В C# действительно аргументы передаются по значению. Вопрос только, что это за аргументы.
Если это аргументы — числа или похожие объекты (они называются типами-значениями), то они передаются таки как есть — передаётся их копия
А если аргументы — объекты классов (они называются ссылочными типами), то по значению передаётся ссылка (то есть как бы указатель, если вы знакомы с C) на объект, а не копия самого объекта. По копии ссылки объект доступен точно так же, как и по оригиналу, и это тот же самый объект.
Почему это сделано так? Дело в том, что не все объекты можно просто склонировать. И даже если это можно, что делать со ссылками на другие объекты, которые содержит данный объект? Клонировать все внутренние объекты? Это слишком долго и слишком сложно (например, что делать, если ссылки выстраиваются в цикл?). А если внутренние объекты не клонировать, возникает та же проблема: сам объект копируется, а внутренние подобъекты всё равно передадутся по ссылке.