aboutsummaryrefslogtreecommitdiffstats
path: root/resources/libraries/python/MLRsearch
diff options
context:
space:
mode:
authorJan Gelety <jgelety@cisco.com>2019-11-12 05:27:43 +0100
committerJan Gelety <jgelety@cisco.com>2019-11-28 18:26:21 +0100
commitd68951ac245150eeefa6e0f4156e4c1b5c9e9325 (patch)
tree487554a7547218d27f0a61ec02b70502c32cdcb4 /resources/libraries/python/MLRsearch
parented0258a440cfad7023d643f717ab78ac568dc59b (diff)
Python3: resources and libraries
Change-Id: I1392c06b1d64f62b141d24c0d42a8e36913b15e2 Signed-off-by: Jan Gelety <jgelety@cisco.com>
Diffstat (limited to 'resources/libraries/python/MLRsearch')
-rw-r--r--resources/libraries/python/MLRsearch/AbstractMeasurer.py7
-rw-r--r--resources/libraries/python/MLRsearch/AbstractSearchAlgorithm.py7
-rw-r--r--resources/libraries/python/MLRsearch/MultipleLossRatioSearch.py176
-rw-r--r--resources/libraries/python/MLRsearch/NdrPdrResult.py27
-rw-r--r--resources/libraries/python/MLRsearch/ReceiveRateInterval.py31
-rw-r--r--resources/libraries/python/MLRsearch/ReceiveRateMeasurement.py16
6 files changed, 141 insertions, 123 deletions
diff --git a/resources/libraries/python/MLRsearch/AbstractMeasurer.py b/resources/libraries/python/MLRsearch/AbstractMeasurer.py
index c9b5987124..622b8fdba6 100644
--- a/resources/libraries/python/MLRsearch/AbstractMeasurer.py
+++ b/resources/libraries/python/MLRsearch/AbstractMeasurer.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Cisco and/or its affiliates.
+# Copyright (c) 2019 Cisco and/or its affiliates.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
@@ -16,11 +16,9 @@
from abc import ABCMeta, abstractmethod
-class AbstractMeasurer(object):
+class AbstractMeasurer(metaclass=ABCMeta):
"""Abstract class defining common API for measurement providers."""
- __metaclass__ = ABCMeta
-
@abstractmethod
def measure(self, duration, transmit_rate):
"""Perform trial measurement and return the result.
@@ -32,4 +30,3 @@ class AbstractMeasurer(object):
:returns: Structure containing the result of the measurement.
:rtype: ReceiveRateMeasurement.ReceiveRateMeasurement
"""
- pass
diff --git a/resources/libraries/python/MLRsearch/AbstractSearchAlgorithm.py b/resources/libraries/python/MLRsearch/AbstractSearchAlgorithm.py
index 08f8b7e0a9..f4f2d3f096 100644
--- a/resources/libraries/python/MLRsearch/AbstractSearchAlgorithm.py
+++ b/resources/libraries/python/MLRsearch/AbstractSearchAlgorithm.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Cisco and/or its affiliates.
+# Copyright (c) 2019 Cisco and/or its affiliates.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
@@ -16,11 +16,9 @@
from abc import ABCMeta, abstractmethod
-class AbstractSearchAlgorithm(object):
+class AbstractSearchAlgorithm(metaclass=ABCMeta):
"""Abstract class defining common API for search algorithms."""
- __metaclass__ = ABCMeta
-
def __init__(self, measurer):
"""Store the rate provider.
@@ -48,4 +46,3 @@ class AbstractSearchAlgorithm(object):
:rtype: NdrPdrResult.NdrPdrResult
"""
# TODO: Do we agree on arguments related to precision or trial duration?
- pass
diff --git a/resources/libraries/python/MLRsearch/MultipleLossRatioSearch.py b/resources/libraries/python/MLRsearch/MultipleLossRatioSearch.py
index 1ecd42e7dd..29b72505de 100644
--- a/resources/libraries/python/MLRsearch/MultipleLossRatioSearch.py
+++ b/resources/libraries/python/MLRsearch/MultipleLossRatioSearch.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Cisco and/or its affiliates.
+# Copyright (c) 2019 Cisco and/or its affiliates.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
@@ -79,7 +79,7 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
TODO: Support configurable number of Packet Loss Ratios.
"""
- class ProgressState(object):
+ class ProgressState:
"""Structure containing data to be passed around in recursion."""
def __init__(
@@ -113,9 +113,10 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
self.minimum_transmit_rate = float(minimum_transmit_rate)
self.maximum_transmit_rate = float(maximum_transmit_rate)
- def __init__(self, measurer, final_relative_width=0.005,
- final_trial_duration=30.0, initial_trial_duration=1.0,
- number_of_intermediate_phases=2, timeout=600.0, doublings=1):
+ def __init__(
+ self, measurer, final_relative_width=0.005,
+ final_trial_duration=30.0, initial_trial_duration=1.0,
+ number_of_intermediate_phases=2, timeout=600.0, doublings=1):
"""Store the measurer object and additional arguments.
:param measurer: Rate provider to use by this search object.
@@ -147,7 +148,6 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
self.timeout = float(timeout)
self.doublings = int(doublings)
-
@staticmethod
def double_relative_width(relative_width):
"""Return relative width corresponding to double logarithmic width.
@@ -173,8 +173,8 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
:rtype: float
"""
return current_bound * (
- 1.0 - MultipleLossRatioSearch.double_relative_width(
- relative_width))
+ 1.0 - MultipleLossRatioSearch.double_relative_width(relative_width)
+ )
@staticmethod
def expand_down(relative_width, doublings, current_bound):
@@ -191,7 +191,8 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
"""
for _ in range(doublings):
relative_width = MultipleLossRatioSearch.double_relative_width(
- relative_width)
+ relative_width
+ )
return current_bound * (1.0 - relative_width)
@staticmethod
@@ -206,8 +207,8 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
:rtype: float
"""
return current_bound / (
- 1.0 - MultipleLossRatioSearch.double_relative_width(
- relative_width))
+ 1.0 - MultipleLossRatioSearch.double_relative_width(relative_width)
+ )
@staticmethod
def expand_up(relative_width, doublings, current_bound):
@@ -224,7 +225,8 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
"""
for _ in range(doublings):
relative_width = MultipleLossRatioSearch.double_relative_width(
- relative_width)
+ relative_width
+ )
return current_bound / (1.0 - relative_width)
@staticmethod
@@ -250,7 +252,8 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
:rtype: float
"""
return current_bound / (
- 1.0 - MultipleLossRatioSearch.half_relative_width(relative_width))
+ 1.0 - MultipleLossRatioSearch.half_relative_width(relative_width)
+ )
def narrow_down_ndr_and_pdr(
self, minimum_transmit_rate, maximum_transmit_rate,
@@ -278,31 +281,32 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
initial_width_goal = self.double_relative_width(initial_width_goal)
max_lo = maximum_transmit_rate * (1.0 - initial_width_goal)
mrr = max(
- minimum_transmit_rate,
- min(max_lo, line_measurement.receive_rate))
+ minimum_transmit_rate, min(max_lo, line_measurement.receive_rate)
+ )
mrr_measurement = self.measurer.measure(
- self.initial_trial_duration, mrr)
+ self.initial_trial_duration, mrr
+ )
# Attempt to get narrower width.
if mrr_measurement.loss_fraction > 0.0:
max2_lo = mrr * (1.0 - initial_width_goal)
mrr2 = min(max2_lo, mrr_measurement.receive_rate)
else:
mrr2 = mrr / (1.0 - initial_width_goal)
- if mrr2 > minimum_transmit_rate and mrr2 < maximum_transmit_rate:
+ if minimum_transmit_rate < mrr2 < maximum_transmit_rate:
line_measurement = mrr_measurement
mrr_measurement = self.measurer.measure(
self.initial_trial_duration, mrr2)
if mrr2 > mrr:
- buf = line_measurement
- line_measurement = mrr_measurement
- mrr_measurement = buf
+ line_measurement, mrr_measurement = \
+ (mrr_measurement, line_measurement)
starting_interval = ReceiveRateInterval(
mrr_measurement, line_measurement)
starting_result = NdrPdrResult(starting_interval, starting_interval)
state = self.ProgressState(
starting_result, self.number_of_intermediate_phases,
self.final_trial_duration, self.final_relative_width,
- packet_loss_ratio, minimum_transmit_rate, maximum_transmit_rate)
+ packet_loss_ratio, minimum_transmit_rate, maximum_transmit_rate
+ )
state = self.ndrpdr(state)
return state.result
@@ -318,15 +322,18 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
"""
# TODO: Implement https://stackoverflow.com/a/24683360
# to avoid the string manipulation if log verbosity is too low.
- logging.info("result before update: %s", state.result)
+ logging.info(f"result before update: {state.result}")
logging.debug(
- "relative widths in goals: %s", state.result.width_in_goals(
- self.final_relative_width))
+ f"relative widths in goals: "
+ f"{state.result.width_in_goals(self.final_relative_width)}"
+ )
measurement = self.measurer.measure(state.duration, transmit_rate)
ndr_interval = self._new_interval(
- state.result.ndr_interval, measurement, 0.0)
+ state.result.ndr_interval, measurement, 0.0
+ )
pdr_interval = self._new_interval(
- state.result.pdr_interval, measurement, state.packet_loss_ratio)
+ state.result.pdr_interval, measurement, state.packet_loss_ratio
+ )
state.result = NdrPdrResult(ndr_interval, pdr_interval)
return state
@@ -387,11 +394,13 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
# "invalid upper bound at maximal rate" case.
new_lo = measurement
- return ReceiveRateInterval(old_lo if new_lo is None else new_lo,
- old_hi if new_hi is None else new_hi)
+ return ReceiveRateInterval(
+ old_lo if new_lo is None else new_lo,
+ old_hi if new_hi is None else new_hi
+ )
def ndrpdr(self, state):
- """Pefrom trials for this phase. Return the new state when done.
+ """Perform trials for this phase. Return the new state when done.
:param state: State before this phase.
:type state: ProgressState
@@ -409,7 +418,8 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
duration_multiplier = state.duration / self.initial_trial_duration
phase_exponent = float(state.phases) / saved_phases
state.duration = self.initial_trial_duration * math.pow(
- duration_multiplier, phase_exponent)
+ duration_multiplier, phase_exponent
+ )
# Shorter durations do not need that narrow widths.
saved_width = state.width_goal
state.width_goal = self.double_relative_width(state.width_goal)
@@ -421,11 +431,12 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
state.phases = saved_phases # Not needed, but just in case.
logging.info(
- "starting iterations with duration %s and relative width goal %s",
- state.duration, state.width_goal)
+ f"starting iterations with duration {state.duration} and relative "
+ f"width goal {state.width_goal}"
+ )
while 1:
if time.time() > start_time + self.timeout:
- raise RuntimeError("Optimized search takes too long.")
+ raise RuntimeError(u"Optimized search takes too long.")
# Order of priorities: invalid bounds (nl, pl, nh, ph),
# then narrowing relative Tr widths.
# Durations are not priorities yet,
@@ -435,14 +446,17 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
pdr_lo = state.result.pdr_interval.measured_low
pdr_hi = state.result.pdr_interval.measured_high
ndr_rel_width = max(
- state.width_goal, state.result.ndr_interval.rel_tr_width)
+ state.width_goal, state.result.ndr_interval.rel_tr_width
+ )
pdr_rel_width = max(
- state.width_goal, state.result.pdr_interval.rel_tr_width)
+ state.width_goal, state.result.pdr_interval.rel_tr_width
+ )
# If we are hitting maximal or minimal rate, we cannot shift,
# but we can re-measure.
- new_tr = self._ndrpdr_loss_fraction(state,
- ndr_lo, ndr_hi, pdr_lo, pdr_hi,
- ndr_rel_width, pdr_rel_width)
+ new_tr = self._ndrpdr_loss_fraction(
+ state, ndr_lo, ndr_hi, pdr_lo, pdr_hi, ndr_rel_width,
+ pdr_rel_width
+ )
if new_tr is not None:
state = self._measure_and_update_state(state, new_tr)
@@ -461,8 +475,9 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
and pdr_lo.loss_fraction > state.packet_loss_ratio):
pdr_rel_width = 0.0
- new_tr = self._ndrpdr_width_goal(state, ndr_lo, pdr_lo,
- ndr_rel_width, pdr_rel_width)
+ new_tr = self._ndrpdr_width_goal(
+ state, ndr_lo, pdr_lo, ndr_rel_width, pdr_rel_width
+ )
if new_tr is not None:
state = self._measure_and_update_state(state, new_tr)
@@ -470,9 +485,10 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
# We do not need to improve width, but there still might be
# some measurements with smaller duration.
- new_tr = self._ndrpdr_duration(state,
- ndr_lo, ndr_hi, pdr_lo, pdr_hi,
- ndr_rel_width, pdr_rel_width)
+ new_tr = self._ndrpdr_duration(
+ state, ndr_lo, ndr_hi, pdr_lo, pdr_hi, ndr_rel_width,
+ pdr_rel_width
+ )
if new_tr is not None:
state = self._measure_and_update_state(state, new_tr)
@@ -480,12 +496,13 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
# Widths are narrow (or lower bound minimal), bound measurements
# are long enough, we can return.
- logging.info("phase done")
+ logging.info(u"phase done")
break
return state
- def _ndrpdr_loss_fraction(self, state, ndr_lo, ndr_hi, pdr_lo, pdr_hi,
- ndr_rel_width, pdr_rel_width):
+ def _ndrpdr_loss_fraction(
+ self, state, ndr_lo, ndr_hi, pdr_lo, pdr_hi, ndr_rel_width,
+ pdr_rel_width):
"""Perform loss_fraction-based trials within a ndrpdr phase
:param state: current state
@@ -509,50 +526,54 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
if ndr_lo.loss_fraction > 0.0:
if ndr_lo.target_tr > state.minimum_transmit_rate:
result = max(
- state.minimum_transmit_rate,
- self.expand_down(
- ndr_rel_width, self.doublings, ndr_lo.target_tr))
- logging.info("ndr lo external %s", result)
+ state.minimum_transmit_rate, self.expand_down(
+ ndr_rel_width, self.doublings, ndr_lo.target_tr
+ )
+ )
+ logging.info(f"ndr lo external {result}")
elif ndr_lo.duration < state.duration:
result = state.minimum_transmit_rate
- logging.info("ndr lo minimal re-measure")
+ logging.info(u"ndr lo minimal re-measure")
if result is None and pdr_lo.loss_fraction > state.packet_loss_ratio:
if pdr_lo.target_tr > state.minimum_transmit_rate:
result = max(
- state.minimum_transmit_rate,
- self.expand_down(
- pdr_rel_width, self.doublings, pdr_lo.target_tr))
- logging.info("pdr lo external %s", result)
+ state.minimum_transmit_rate, self.expand_down(
+ pdr_rel_width, self.doublings, pdr_lo.target_tr
+ )
+ )
+ logging.info(f"pdr lo external {result}")
elif pdr_lo.duration < state.duration:
result = state.minimum_transmit_rate
- logging.info("pdr lo minimal re-measure")
+ logging.info(u"pdr lo minimal re-measure")
if result is None and ndr_hi.loss_fraction <= 0.0:
if ndr_hi.target_tr < state.maximum_transmit_rate:
result = min(
- state.maximum_transmit_rate,
- self.expand_up(
- ndr_rel_width, self.doublings, ndr_hi.target_tr))
- logging.info("ndr hi external %s", result)
+ state.maximum_transmit_rate, self.expand_up(
+ ndr_rel_width, self.doublings, ndr_hi.target_tr
+ )
+ )
+ logging.info(f"ndr hi external {result}")
elif ndr_hi.duration < state.duration:
result = state.maximum_transmit_rate
- logging.info("ndr hi maximal re-measure")
+ logging.info(u"ndr hi maximal re-measure")
if result is None and pdr_hi.loss_fraction <= state.packet_loss_ratio:
if pdr_hi.target_tr < state.maximum_transmit_rate:
result = min(
- state.maximum_transmit_rate,
- self.expand_up(
- pdr_rel_width, self.doublings, pdr_hi.target_tr))
- logging.info("pdr hi external %s", result)
+ state.maximum_transmit_rate, self.expand_up(
+ pdr_rel_width, self.doublings, pdr_hi.target_tr
+ )
+ )
+ logging.info(f"pdr hi external {result}")
elif pdr_hi.duration < state.duration:
result = state.maximum_transmit_rate
- logging.info("ndr hi maximal re-measure")
+ logging.info(u"ndr hi maximal re-measure")
return result
- def _ndrpdr_width_goal(self, state, ndr_lo, pdr_lo,
- ndr_rel_width, pdr_rel_width):
+ def _ndrpdr_width_goal(
+ self, state, ndr_lo, pdr_lo, ndr_rel_width, pdr_rel_width):
"""Perform width_goal-based trials within a ndrpdr phase
:param state: current state
@@ -573,18 +594,19 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
# We have to narrow NDR width first, as NDR internal search
# can invalidate PDR (but not vice versa).
result = self.half_step_up(ndr_rel_width, ndr_lo.target_tr)
- logging.info("Bisecting for NDR at %s", result)
+ logging.info(f"Bisecting for NDR at {result}")
elif pdr_rel_width > state.width_goal:
- # PDR iternal search.
+ # PDR internal search.
result = self.half_step_up(pdr_rel_width, pdr_lo.target_tr)
- logging.info("Bisecting for PDR at %s", result)
+ logging.info(f"Bisecting for PDR at {result}")
else:
result = None
return result
@staticmethod
- def _ndrpdr_duration(state, ndr_lo, pdr_lo, ndr_hi, pdr_hi,
- ndr_rel_width, pdr_rel_width):
+ def _ndrpdr_duration(
+ state, ndr_lo, pdr_lo, ndr_hi, pdr_hi, ndr_rel_width,
+ pdr_rel_width):
"""Perform duration-based trials within a ndrpdr phase
:param state: current state
@@ -608,18 +630,18 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
# creating invalid bounds to resolve (thus broadening width).
if ndr_lo.duration < state.duration:
result = ndr_lo.target_tr
- logging.info("re-measuring NDR lower bound")
+ logging.info(u"re-measuring NDR lower bound")
elif pdr_lo.duration < state.duration:
result = pdr_lo.target_tr
- logging.info("re-measuring PDR lower bound")
+ logging.info(u"re-measuring PDR lower bound")
# Except when lower bounds have high loss fraction, in that case
# we do not need to re-measure _upper_ bounds.
elif ndr_hi.duration < state.duration and ndr_rel_width > 0.0:
result = ndr_hi.target_tr
- logging.info("re-measuring NDR upper bound")
+ logging.info(u"re-measuring NDR upper bound")
elif pdr_hi.duration < state.duration and pdr_rel_width > 0.0:
result = pdr_hi.target_tr
- logging.info("re-measuring PDR upper bound")
+ logging.info(u"re-measuring PDR upper bound")
else:
result = None
return result
diff --git a/resources/libraries/python/MLRsearch/NdrPdrResult.py b/resources/libraries/python/MLRsearch/NdrPdrResult.py
index 7b8cfd6449..3454ef1957 100644
--- a/resources/libraries/python/MLRsearch/NdrPdrResult.py
+++ b/resources/libraries/python/MLRsearch/NdrPdrResult.py
@@ -13,11 +13,10 @@
"""Module defining NdrPdrResult class."""
-from resources.libraries.python.MLRsearch.ReceiveRateInterval \
- import ReceiveRateInterval
+from .ReceiveRateInterval import ReceiveRateInterval
-class NdrPdrResult(object):
+class NdrPdrResult:
"""Two measurement intervals, return value of search algorithms.
Partial fraction is NOT part of the result. Pdr interval should be valid
@@ -34,11 +33,13 @@ class NdrPdrResult(object):
# TODO: Type checking is not very pythonic,
# perhaps users can fix wrong usage without it?
if not isinstance(ndr_interval, ReceiveRateInterval):
- raise TypeError("ndr_interval, is not a ReceiveRateInterval: "
- "{ndr!r}".format(ndr=ndr_interval))
+ raise TypeError(
+ f"ndr_interval, is not a ReceiveRateInterval: {ndr_interval!r}"
+ )
if not isinstance(pdr_interval, ReceiveRateInterval):
- raise TypeError("pdr_interval, is not a ReceiveRateInterval: "
- "{pdr!r}".format(pdr=pdr_interval))
+ raise TypeError(
+ f"pdr_interval, is not a ReceiveRateInterval: {pdr_interval!r}"
+ )
self.ndr_interval = ndr_interval
self.pdr_interval = pdr_interval
@@ -51,16 +52,14 @@ class NdrPdrResult(object):
:returns: Message containing NDR and PDR widths in goals.
:rtype: str
"""
- return "ndr {ndr_in_goals}; pdr {pdr_in_goals}".format(
- ndr_in_goals=self.ndr_interval.width_in_goals(relative_width_goal),
- pdr_in_goals=self.pdr_interval.width_in_goals(relative_width_goal))
+ return f"ndr {self.ndr_interval.width_in_goals(relative_width_goal)};" \
+ f" pdr {self.pdr_interval.width_in_goals(relative_width_goal)}"
def __str__(self):
"""Return string as tuple of named values."""
- return "NDR={ndr!s};PDR={pdr!s}".format(
- ndr=self.ndr_interval, pdr=self.pdr_interval)
+ return f"NDR={self.ndr_interval!s};PDR={self.pdr_interval!s}"
def __repr__(self):
"""Return string evaluable as a constructor call."""
- return "NdrPdrResult(ndr_interval={ndr!r},pdr_interval={pdr!r})".format(
- ndr=self.ndr_interval, pdr=self.pdr_interval)
+ return f"NdrPdrResult(ndr_interval={self.ndr_interval!r}," \
+ f"pdr_interval={self.pdr_interval!r})"
diff --git a/resources/libraries/python/MLRsearch/ReceiveRateInterval.py b/resources/libraries/python/MLRsearch/ReceiveRateInterval.py
index ec3cbb7462..eff23e8bcc 100644
--- a/resources/libraries/python/MLRsearch/ReceiveRateInterval.py
+++ b/resources/libraries/python/MLRsearch/ReceiveRateInterval.py
@@ -15,11 +15,10 @@
import math
-from resources.libraries.python.MLRsearch.ReceiveRateMeasurement \
- import ReceiveRateMeasurement
+from .ReceiveRateMeasurement import ReceiveRateMeasurement
-class ReceiveRateInterval(object):
+class ReceiveRateInterval:
"""Structure defining two Rr measurements, and their relation."""
def __init__(self, measured_low, measured_high):
@@ -33,11 +32,15 @@ class ReceiveRateInterval(object):
# TODO: Type checking is not very pythonic,
# perhaps users can fix wrong usage without it?
if not isinstance(measured_low, ReceiveRateMeasurement):
- raise TypeError("measured_low is not a ReceiveRateMeasurement: "
- "{low!r}".format(low=measured_low))
+ raise TypeError(
+ f"measured_low is not a ReceiveRateMeasurement: "
+ f"{measured_low!r}"
+ )
if not isinstance(measured_high, ReceiveRateMeasurement):
- raise TypeError("measured_high is not a ReceiveRateMeasurement: "
- "{high!r}".format(high=measured_high))
+ raise TypeError(
+ f"measured_high is not a ReceiveRateMeasurement: "
+ f"{measured_high!r}"
+ )
self.measured_low = measured_low
self.measured_high = measured_high
# Declare secondary quantities to appease pylint.
@@ -51,9 +54,11 @@ class ReceiveRateInterval(object):
"""Sort bounds by target Tr, compute secondary quantities."""
if self.measured_low.target_tr > self.measured_high.target_tr:
self.measured_low, self.measured_high = (
- self.measured_high, self.measured_low)
+ self.measured_high, self.measured_low
+ )
self.abs_tr_width = (
- self.measured_high.target_tr - self.measured_low.target_tr)
+ self.measured_high.target_tr - self.measured_low.target_tr
+ )
self.rel_tr_width = self.abs_tr_width / self.measured_high.target_tr
def width_in_goals(self, relative_width_goal):
@@ -75,11 +80,9 @@ class ReceiveRateInterval(object):
def __str__(self):
"""Return string as half-open interval."""
- return "[{low!s};{high!s})".format(
- low=self.measured_low, high=self.measured_high)
+ return f"[{self.measured_low!s};{self.measured_high!s})"
def __repr__(self):
"""Return string evaluable as a constructor call."""
- return ("ReceiveRateInterval(measured_low={low!r}"
- ",measured_high={high!r})".format(
- low=self.measured_low, high=self.measured_high))
+ return f"ReceiveRateInterval(measured_low={self.measured_low!r}," \
+ f"measured_high={self.measured_high!r})"
diff --git a/resources/libraries/python/MLRsearch/ReceiveRateMeasurement.py b/resources/libraries/python/MLRsearch/ReceiveRateMeasurement.py
index d052ebd3bf..31a6f8202e 100644
--- a/resources/libraries/python/MLRsearch/ReceiveRateMeasurement.py
+++ b/resources/libraries/python/MLRsearch/ReceiveRateMeasurement.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Cisco and/or its affiliates.
+# Copyright (c) 2019 Cisco and/or its affiliates.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
@@ -14,7 +14,7 @@
"""Module defining ReceiveRateMeasurement class."""
-class ReceiveRateMeasurement(object):
+class ReceiveRateMeasurement:
"""Structure defining the result of single Rr measurement."""
def __init__(self, duration, target_tr, transmit_count, loss_count):
@@ -43,12 +43,12 @@ class ReceiveRateMeasurement(object):
def __str__(self):
"""Return string reporting input and loss fraction."""
- return "d={dur!s},Tr={rate!s},Df={frac!s}".format(
- dur=self.duration, rate=self.target_tr, frac=self.loss_fraction)
+ return f"d={self.duration!s},Tr={self.target_tr!s}," \
+ f"Df={self.loss_fraction!s}"
def __repr__(self):
"""Return string evaluable as a constructor call."""
- return ("ReceiveRateMeasurement(duration={dur!r},target_tr={rate!r}"
- ",transmit_count={trans!r},loss_count={loss!r})".format(
- dur=self.duration, rate=self.target_tr,
- trans=self.transmit_count, loss=self.loss_count))
+ return f"ReceiveRateMeasurement(duration={self.duration!r}," \
+ f"target_tr={self.target_tr!r}," \
+ f"transmit_count={self.transmit_count!r}," \
+ f"loss_count={self.loss_count!r})"