Files

97 lines
3.3 KiB
Python

from decimal import Decimal, InvalidOperation
import re
COUNT = 20
HEADER = "Лабораторная работа №1"
TASK = "Задача: найти максимальный элемент списка и поменять его с первым"
FORMAT_HINT = "Можно вводить только целые числа: 10, -5, 1e20\n"
INTEGER_INPUT_PATTERN = re.compile(r"^[+-]?\d+(?:[eE][+-]?\d+)?$")
def parse_number(user_input: str) -> tuple[Decimal, bool]:
normalized = user_input.strip()
if normalized == "":
raise ValueError("Ошибка: пустой ввод. Повторите.")
if not INTEGER_INPUT_PATTERN.fullmatch(normalized):
raise ValueError("Ошибка: введите целое число (например, 10 или 1e3).")
used_scientific = "e" in normalized.lower()
try:
number = Decimal(normalized)
except InvalidOperation as error:
raise ValueError("Ошибка: введите целое число (например, 10 или 1e3).") from error
if not number.is_finite():
raise ValueError("Ошибка: число должно быть конечным.")
if number != number.to_integral_value():
raise ValueError("Ошибка: введите целое число (например, 10 или 1e3).")
return number, used_scientific
def collect_numbers(count: int) -> list[tuple[Decimal, bool]]:
numbers: list[tuple[Decimal, bool]] = []
while len(numbers) < count:
raw_value = input(f"Введите число №{len(numbers) + 1}: ")
try:
numbers.append(parse_number(raw_value))
except ValueError as error:
print(error)
return numbers
def swap_first_with_max(numbers: list[tuple[Decimal, bool]]) -> tuple[tuple[Decimal, bool], int]:
values = [value for value, _ in numbers]
max_value = max(values)
max_index = values.index(max_value)
max_number = numbers[max_index]
numbers[0], numbers[max_index] = numbers[max_index], numbers[0]
return max_number, max_index
# Красивый вывод Decimal без лишних нулей
def format_decimal(value: Decimal) -> str:
normalized = value.normalize()
# Если число целое
if normalized == normalized.to_integral():
return str(normalized.quantize(Decimal(1)))
return format(normalized, 'f').rstrip('0').rstrip('.')
def format_number(value: Decimal, used_scientific: bool) -> str:
if used_scientific:
return f"{value.normalize():e}".replace("e+0", "e+").replace("e-0", "e-")
return format_decimal(value)
def format_number_list(numbers: list[tuple[Decimal, bool]]) -> str:
return "[" + ", ".join(format_number(v, sci) for v, sci in numbers) + "]"
def main() -> None:
print(HEADER)
print(TASK)
print(FORMAT_HINT)
numbers = collect_numbers(COUNT)
print("\nИсходный список:", format_number_list(numbers))
max_number, max_index = swap_first_with_max(numbers)
print("Максимальный элемент:", format_number(*max_number))
print("Индекс максимального элемента:", max_index)
print("\nСписок после обмена:", format_number_list(numbers))
if __name__ == "__main__":
main()