|
import argparse |
|
from typing import Dict, List |
|
|
|
# Constants for unit conversion |
|
UNITS: Dict[str, float] = { |
|
"b": 1, |
|
"B": 8, |
|
"Kb": 1e3, |
|
"KB": 8e3, |
|
"Mb": 1e6, |
|
"MB": 8e6, |
|
"Gb": 1e9, |
|
"GB": 8e9, |
|
"Tb": 1e12, |
|
"TB": 8e12, |
|
} |
|
|
|
|
|
def parse_rate_input(rate_input: str) -> float: |
|
""" |
|
Parses the rate input and returns the rate in bits per second. |
|
|
|
Args: |
|
rate_input (str): The rate input in the format 'valueUnit/timeUnit' (e.g., '400MB/min'). |
|
|
|
Returns: |
|
float: The rate converted to bits per second. |
|
""" |
|
try: |
|
value_unit, time_unit = rate_input.split("/") |
|
except ValueError: |
|
raise ValueError( |
|
"Invalid rate input. The rate input must be in the format 'valueUnit/timeUnit' (e.g., '400MB/min')." |
|
) |
|
value, unit = float(value_unit[:-2]), value_unit[-2:] |
|
if unit not in UNITS: |
|
raise ValueError(f"Invalid unit '{unit}'. Supported units are: {', '.join(UNITS.keys())}.") |
|
rate_bits = convert_to_bits(value, unit) |
|
try: |
|
time_seconds = convert_time_unit_to_seconds(time_unit) |
|
except ValueError as e: |
|
raise e |
|
return rate_bits / time_seconds |
|
|
|
|
|
def convert_time_unit_to_seconds(time_unit: str) -> float: |
|
""" |
|
Converts the given time unit to seconds. |
|
|
|
Args: |
|
time_unit (str): The time unit (e.g., 'min', 's'). |
|
|
|
Returns: |
|
float: The time in seconds. |
|
""" |
|
if time_unit == "min": |
|
return 60 |
|
elif time_unit == "s": |
|
return 1 |
|
else: |
|
raise ValueError("Unsupported time unit. Supported units are 'min' and 's'.") |
|
|
|
|
|
def convert_to_bits(value: float, unit: str) -> float: |
|
""" |
|
Converts the given value to bits. |
|
|
|
Args: |
|
value (float): The value to be converted. |
|
unit (str): The unit of the given value (e.g., 'MB', 'Gb'). |
|
|
|
Returns: |
|
float: The value converted to bits. |
|
""" |
|
return value * UNITS.get(unit, 1) |
|
|
|
|
|
def humanize_units(value: float) -> str: |
|
""" |
|
Humanizes the value by scaling it to |
|
Args: |
|
value (float): The value in bits. |
|
|
|
Returns: |
|
str: The humanized value with the appropriate unit. |
|
""" |
|
for unit in ["b", "Kb", "Mb", "Gb", "Tb"]: |
|
if value < 1000: |
|
return f"{value:.2f} {unit}" |
|
value /= 1000 |
|
return f"{value:.2f} Tb" # Fallback to Terabits if extremely large |
|
|
|
|
|
def format_output(value: float, output_unit: str) -> str: |
|
""" |
|
Formats the output value in the specified output unit. |
|
|
|
Args: |
|
value (float): The value in bits to be formatted. |
|
output_unit (str): The output unit. |
|
|
|
Returns: |
|
str: The formatted value with the output unit. |
|
""" |
|
# Convert the value to the specified output unit |
|
value_in_output_unit = value / UNITS[output_unit] |
|
return f"{value_in_output_unit:.2f} {output_unit}/s" |
|
|
|
|
|
def process_rates(rates: List[str], output_unit: str) -> None: |
|
""" |
|
Processes a list of rate inputs and prints the formatted output. |
|
|
|
Args: |
|
rates (List[str]): A list of rate inputs (e.g., ['400MB/min', '3Gb/s']). |
|
output_unit (str): The unit for output display. |
|
""" |
|
for rate in rates: |
|
rate_bits_per_second = parse_rate_input(rate) |
|
formatted_rate = format_output(rate_bits_per_second, output_unit) |
|
print(formatted_rate) |
|
|
|
|
|
def main() -> None: |
|
# Set up argument parsing |
|
parser = argparse.ArgumentParser(description="Compare network rates.") |
|
parser.add_argument( |
|
"rates", |
|
type=str, |
|
nargs="+", # '+' means one or more arguments |
|
help="List of rates to compare (e.g., '400MB/min 3Gb/s').", |
|
) |
|
parser.add_argument( |
|
"--output_unit", |
|
type=str, |
|
default="Mb", |
|
choices=UNITS.keys(), |
|
help="Output unit for displaying rates (default: 'Mb').", |
|
) |
|
args = parser.parse_args() |
|
|
|
# Process the rates |
|
try: |
|
# Process the rates |
|
process_rates(args.rates, args.output_unit) |
|
except Exception as e: |
|
print(f"Error: {e}") |
|
|
|
if __name__ == "__main__": |
|
main() |