Python, усеченный после сотни?

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

Реактивные расширения в .NET 4.5 были созданы для обработки именно этих сценариев. Вы можете легко использовать их для обеспечения такой функциональности с помощью таких методов, как Throttle , Buffer , Window или Sample . Вы публикуете события в субъекте , применяете к нему одну из оконных функций, например, чтобы получать уведомление, только если не было активности в течение X секунд или событий Y, а затем подписываетесь на уведомление.

Subject _mySubject=new Subject();
....
var eventSequenc=mySubject.Throttle(TimeSpan.FromSeconds(1))
                          .Subscribe(events=>MySubscriptionMethod(events));

Дроссель возвращает последнее событие в скользящем окне, только если в окне не было других событий. Любое событие сбрасывает окно.

Вы можете найти очень хороший обзор сдвинутых во времени функций здесь

Когда ваш код получает событие, вам нужно только опубликовать его в теме с помощью OnNext:

_mySubject.OnNext(MyEventData);

Если ваше аппаратное событие выглядит как типичное событие .NET, вы можете обойти тему и ручную публикацию с помощью Observable.FromEventPattern , как показано здесь :

var mySequence = Observable.FromEventPattern(
    h => _myDevice.MyEvent += h,
    h => _myDevice.MyEvent -= h);  
_mySequence.Throttle(TimeSpan.FromSeconds(1))
           .Subscribe(events=>MySubscriptionMethod(events));

Вы также можете создавать наблюдаемые из задач, комбинировать последовательности событий с операторами LINQ для запроса, например: пары различных аппаратных событий с Zip, использовать другой источник событий для привязки Throttle / Buffer и т. Д., Добавлять задержки и многое другое . [+1122]

Reactive Extensions доступны в виде пакета NuGet , поэтому их очень легко добавить в ваш проект.

Книга Стивена Клири « Параллелизм в C # Cookbook » является очень хорошим ресурсом по Reactive Extensions и объясняет, как вы можете использовать его и как он сочетается с остальными параллельных API в .NET, таких как Tasks, Events и т. д.

Введение в Rx - превосходная серия статей (здесь я скопировал примеры) с несколькими примерами.

ОБНОВЛЕНИЕ

Используя ваш конкретный пример, вы можете сделать что-то вроде:

IObservable _myObservable;

private MachineClass connect()
{

    MachineClass rpc = new MachineClass();
   _myObservable=Observable
                 .FromEventPattern(
                            h=> rpc.RxVARxH += h,
                            h=> rpc.RxVARxH -= h)
                 .Throttle(TimeSpan.FromSeconds(1));
   _myObservable.Subscribe(machine=>eventRxVARxH(machine));
    return rpc;
}

Конечно, это может быть значительно улучшено - как наблюдаемое, так и подписка должны быть расположены в какой-то момент. Этот код предполагает, что вы управляете только одним устройством. Если у вас много устройств, вы можете создать наблюдаемое внутри класса, чтобы каждый MachineClass выставлял и располагал свою собственную наблюдаемую.

11
задан 9 June 2009 в 00:29
поделиться

5 ответов

Если вы работаете с денежными суммами, я настоятельно рекомендую вместо этого использовать десятичный класс Python: http://docs.python.org/library/decimal.html

6
ответ дан 3 December 2019 в 02:53
поделиться

Форматирование строки в python 2.x должно сделать это за вас:

>>> print '%.2f' % 315.15321531321
315.15

Это ограничивает строковое представление двумя знаками после запятой. Обратите внимание, что если вы используете round (315.153215, 2) , вы получите другое значение с плавающей запятой, что, естественно, неточно (или слишком точно, в зависимости от того, как вы на это смотрите):

>>> round(315.15321531321, 2)
315.14999999999998

Технически, round () правильный, но он не «усекает» результаты, как вы запрашивали в 315.15 . Вдобавок, если округлить значение вроде 315,157, получится что-то близкое к 315,16 ... не уверен, что вы имеете в виду под «усечением».

13
ответ дан 3 December 2019 в 02:53
поделиться

У вас есть несколько вариантов - вы можете округлить число с помощью round (), однако это может внести некоторые неточности (например, 315,15 может округляться до 315,150000003). Если вы просто хотите обрезать значение float при его отображении, вы можете указать ширину вывода с помощью printf ("%. 2f", mynumber). Это, вероятно, лучшее решение, поскольку, не зная больше о вашем конкретном приложении, в общем случае рекомендуется сохранить всю длину числа для расчета.

1
ответ дан 3 December 2019 в 02:53
поделиться

Встроенная функция round () :

>>> num = 315.1532153132
>>> round(num, 2)
3.1499999999999998
1
ответ дан 3 December 2019 в 02:53
поделиться

Если вы просто хотите отобразить его в сокращенном виде, вы можете использовать «% f» флаг форматирования:

value = 315.123123123
print "Value is: %.2f" % value

Если вы действительно хотите отрезать «дополнительные» цифры, выполните что-то вроде:

from math import trunc
value = trunc(value*100)/100
2
ответ дан 3 December 2019 в 02:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: