diff --git a/lab1.py b/.shii/lab1.py similarity index 100% rename from lab1.py rename to .shii/lab1.py diff --git a/lab2.py b/.shii/lab2.py similarity index 100% rename from lab2.py rename to .shii/lab2.py diff --git a/lab1/main.py b/lab1/main.py new file mode 100644 index 0000000..55e5bc6 --- /dev/null +++ b/lab1/main.py @@ -0,0 +1,88 @@ +from decimal import Decimal, InvalidOperation + +COUNT = 20 +HEADER = "Лабораторная работа №1" +TASK = "Задача: найти максимальный элемент списка и поменять его с первым" +FORMAT_HINT = "Можно вводить числа в формате: 10, -5.3, 1e20\n" + + +def parse_number(user_input: str) -> tuple[Decimal, bool]: + normalized = user_input.strip() + if normalized == "": + raise ValueError("Ошибка: пустой ввод. Повторите.") + + used_scientific = "e" in normalized.lower() + normalized = normalized.replace(",", ".") + + try: + number = Decimal(normalized) + except InvalidOperation as error: + raise ValueError("Ошибка: это не число. Попробуйте снова.") from error + + if not number.is_finite(): + raise ValueError("Ошибка: число должно быть конечным.") + + 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()