Как говорилось в предыдущей статье, программа – это, чаще всего, обработчик данных, который требует как ввода, так и вывода этих самых данных. В этом уроке мы поговорим о самом простом способе получить данные от пользователя в Python: считать их из консоли функцией input().
Ввод в Python
В Питоне есть функция input(), предназначенная для считывания данных, введённых пользователем в консоль с клавиатуры.
Когда вызывается input(), поток выполнения программы останавливается до тех пор, пока пользователь не произведет ввод в терминал.
Для завершения ввода пользователь должен нажать «Enter».
После этого функция input() считывает введённые пользователем данные и автоматически преобразует к строковому типу, даже если это цифры:
переменная = input()
print('переменная:', переменная)
print(type(переменная))
# Вывод:
2
переменная: 2
<class 'str'>
Преобразование вводимых данных
Если Вам необходимо использовать данные, введённые пользователем не как строковые, Вам придётся самостоятельно преобразовать тип данных. Мы уже рассказывали о преобразовании типов, но давайте освежим знания.
Input() в int
Если Вам нужно получить целое число, используйте функцию int():
переменная = input()
print('переменная:', переменная)
print(type(переменная))
новая_переменная = int(переменная)
print('новая_переменная:', новая_переменная)
print(type(новая_переменная))
# Вывод:
3
переменная: 3
<class 'str'>
новая_переменная: 3
<class 'int'>
То же самое можно сделать гораздо короче, используя мощь Питона:
print('переменная: {}'.format(переменная := int(input())), type(переменная), sep='\n')
# Вывод:
10
переменная: 10
<class 'int'>
Input() в float
Если нужно получить число с плавающей точкой (не целое), примените функцию float().
переменная = float(input())
print('переменная:', переменная)
print(type(переменная))
# Вывод:
5
переменная: 5.0
<class 'float'>
Input() в list (список)
Используя некоторые хитрости, можно преобразовать данные, возвращаемые функцией input() в список или другую списко-подобную коллекцию. Для этого надо при помощи метода строки split() разбить её на элементы, используя какой-либо разделитель. Пример с пробелом, в качестве разделителя:
переменная = input().split()
print(переменная)
print(type(переменная))
# Вывод:
1 2 3
['1', '2', '3']
<class 'list'>
Пример с запятой в качестве разделителя:
переменная = input().split(',')
print(переменная)
print(type(переменная))
# Вывод:
1,2,3
['1', '2', '3']
<class 'list'>
Во обоих случаях элементы всё равно имеют строковый тип:
переменная = input().split(',')
print(переменная)
print(type(переменная))
print(list(map(type, переменная)))
# Вывод:
1,2,3
['1', '2', '3']
<class 'list'>
[<class 'str'>, <class 'str'>, <class 'str'>]
Если же Вам нужно преобразовать и их, можно снова использовать функцию преобразования типов в связке с циклом:
переменная = list()
for element in input().split():
переменная.append(complex(element))
print(переменная)
print([type(num) for num in переменная])
# Вывод:
999 333 666
[(999+0j), (333+0j), (666+0j)]
[<class 'complex'>, <class 'complex'>, <class 'complex'>]
Можно так же использовать списковое включение, что выглядит лаконичнее:
переменная = [complex(element) for element in input().split()]
print(переменная)
print([type(num) for num in переменная])
# Вывод:
999 333 666
[(999+0j), (333+0j), (666+0j)]
[<class 'complex'>, <class 'complex'>, <class 'complex'>]
Но, пожалуй самый «чистый» и производительный способ сделать это, расположен в самых недрах функционального программирования – функция высшего порядка:
переменная = list(map(complex, input().split()))
print(переменная)
print([type(num) for num in переменная])
# Вывод:
999 333 666
[(999+0j), (333+0j), (666+0j)]
[<class 'complex'>, <class 'complex'>, <class 'complex'>]
input() в dict (словарь)
К сожалению, попытки простого преобразования данных input() в dict приводят лишь к извращениям:
переменная = dict()
введённые_данные = input().split()
for i, element in enumerate(введённые_данные):
if i % 2 == 0 and len(введённые_данные) - i > 1:
переменная[element] = complex(введённые_данные[i + 1])
print(переменная)
print('Тип ключей:', [type(num) for num in переменная])
print('Тип значений:', [type(num) for num in переменная.values()])
# Вывод:
первый_элемент 12 второй_элемент 54
{'первый_элемент': (12+0j), 'второй_элемент': (54+0j)}
Тип ключей: [<class 'str'>, <class 'str'>]
Тип значений: [<class 'complex'>, <class 'complex'>]
Но, как видите, это работает.
Ввод в несколько переменных
Если необходимо заполнить одним вводом с клавиатуры сразу несколько переменных, воспользуйтесь распаковкой:
переменная, ещё_одна_переменная, последняя_переменная = input().split()
print('Переменная:', переменная)
print('Ещё_одна_переменная:', ещё_одна_переменная)
print('Последняя_переменная:', последняя_переменная)
# Вывод:
Не_верь Не_бойся Не_проси
Переменная: Не_верь
Ещё_одна_переменная: Не_бойся
Последняя_переменная: Не_проси
Не забывайте, что все переменные после распаковки будут строкового типа, а так же, что вводимых элементов должно быть столько же, сколько переменных:
- если введенных значений больше чем переменных, Вы получите ошибку – ValueError: too many values to unpack (expected 3);
- если введенных значений меньше чем переменных, Вы получите ошибку – ValueError: not enough values to unpack (expected 3, got 2);
Этого можно избежать, если использовать ещё одну хитрость: распаковку слева))
переменная, ещё_одна_переменная, *остальные_элементы = input().split()
print('Переменная:', переменная)
print('Ещё_одна_переменная:', ещё_одна_переменная)
print('Остальные_элементы:', остальные_элементы)
# Вывод:
Не_верь Не_бойся Не_проси И_успокойся
Переменная: Не_верь
Ещё_одна_переменная: Не_бойся
Остальные_элементы: ['Не_проси', 'И_успокойся']
Параметр prompt
Если использовать функцию input() так, как мы это делали в примерах выше, пользователю будет не ясно, что от него требуется, ведь программа просто остановится. Хорошо было бы вывести пояснение:
print('Введите что-нибудь: ')
input()
# Вывод:
Введите что-нибудь:
что-нибудь
К счастью, эту возможность обеспечивает сама функция input() – Вы можете передать сообщение для пользователя как позиционный аргумент функции (или по имени параметра promt, но так никто не делает) и сообщение будет отображено на экране:
input('Введите что-нибудь: ')
# Вывод:
Введите что-нибудь: что-нибудь
Обработка исключений ввода
Древняя компьютерная мудрость гласит: «не доверяй пользователю». Дело в том, что пользовательский ввод – это место, через которое информация попадает внутрь программы. Здесь можно провести аналогию со ртом, через который пища попадает в организм. Вы ведь не всё подряд засовываете в рот? Очень надеемся, что так и есть!
Продолжая аналогию, можно сказать, что пища (пользовательский ввод) может быть опасной (вирусы, sql инъекции и прочие атаки) или просто не съедобной (ожидаем от пользователя электронный адрес, а он вводит домашний).
Есть целый ряд профессий, направленных на борьбу с этими угрозами: пинтестеры и различные инженеры по информационной безопасности.
В целом, всегда стоит придерживаться правила: пользовательский ввод должен быть проверен!
Давайте немного повоюем с воображаемым программистом. Вот код, который доверчиво ожидает от пользователя ввода числа от 1 до 100:
from math import sqrt
переменная = input('Введите число от 1 до 100: ')
переменная = int(переменная)
print('Корень Вашего числа равен: ', sqrt(переменная))
# Вывод:
Введите число от 1 до 100: шесть
Traceback (most recent call last):
File "C:\Users\ivand\AppData\Roaming\JetBrains\PyCharm2021.2\scratches\scratch.py", line 4, in <module>
переменная = int(переменная)
ValueError: invalid literal for int() with base 10: 'шесть'
Process finished with exit code 1
Добавим проверку, что вводятся не буквы:
from math import sqrt
переменная = input('Введите число от 1 до 100: ')
while True:
for i in переменная:
if i.isalpha():
print('Введите число (ЦИФРАМИ)!')
переменная = input('Введите число от 1 до 100: ')
break
else:
break
переменная = int(переменная)
print('Корень Вашего числа равен: ', sqrt(переменная))
# Вывод:
Введите число от 1 до 100: шесть
Введите число (ЦИФРАМИ)!
Введите число от 1 до 100: ,,
Traceback (most recent call last):
File "C:\Users\ivand\AppData\Roaming\JetBrains\PyCharm2021.2\scratches\scratch.py", line 13, in <module>
переменная = int(переменная)
ValueError: invalid literal for int() with base 10: ',,'
Process finished with exit code 1
Что ж, добавим проверку, что вводится именно число:
from math import sqrt
переменная = input('Введите число от 1 до 100: ')
while True:
for i in переменная:
if not i.isnumeric():
print('Введите число (ЦИФРАМИ)!')
переменная = input('Введите число от 1 до 100: ')
break
else:
break
переменная = int(переменная)
print('Корень Вашего числа равен: ', sqrt(переменная))
# Вывод:
Введите число от 1 до 100: 20.5
Введите число (ЦИФРАМИ)!
Введите число от 1 до 100: Ⅻ
Traceback (most recent call last):
File "C:\Users\ivand\AppData\Roaming\JetBrains\PyCharm2021.2\scratches\scratch.py", line 13, in <module>
переменная = int(переменная)
ValueError: invalid literal for int() with base 10: 'Ⅻ'
Process finished with exit code 1
Всё, хватит это терпеть! Проверяем, что пользователь вводит именно целое число:
from math import sqrt
переменная = input('Введите число от 1 до 100: ')
while True:
for i in переменная:
if not i.isdigit():
print('Введите ЧИСЛО (ТОЛЬКО ЦИФРЫ)!!!')
переменная = input('Введите число от 1 до 100: ')
break
else:
break
переменная = int(переменная)
print('Корень Вашего числа равен: ', sqrt(переменная))
# Вывод:
Введите число от 1 до 100: Ⅻ
Введите ЧИСЛО (ТОЛЬКО ЦИФРЫ)!!!
Введите число от 1 до 100: 1000000
Корень Вашего числа равен: 1000.0
Process finished with exit code 0
Здесь, формально, всё прошло гладко, но введённое значение не входит в требуемый диапазон. Как видите, это не так просто. Ещё один способ – принимать любой пользовательский ввод и потом «ловить» ошибки внутри программы:
from math import sqrt
while True:
переменная = input('Введите число от 1 до 100: ')
try:
переменная = int(переменная)
except:
print('Введите ЧИСЛО (ТОЛЬКО ЦИФРЫ)!!!')
else:
break
print('Корень Вашего числа равен: ', sqrt(переменная))
# Вывод:
Введите число от 1 до 100: шесть
Введите ЧИСЛО (ТОЛЬКО ЦИФРЫ)!!!
Введите число от 1 до 100: 6
Корень Вашего числа равен: 2.449489742783178
Process finished with exit code 0
Но обработка исключений не такая простая тема, как может показаться (подробнее можете ознакомиться с исключениями в нашей статье).
К тому же, этот подход не защищает от направленных атак:
while True:
переменная = input('Введите выражение: ')
try:
print('Результат выражения:', eval(переменная))
except:
print('Введите выражение на языке Python!')
else:
break
# Вывод:
Введите выражение: Попытка атаки
Введите выражение на языке Python!
Введите выражение: 'Я' + ' загружаю' + ' страшный' + ' вирус!'
Результат выражения: Я загружаю страшный вирус!
Эмуляция терминала с использованием функции input().
Для того, чтоб продемонстрировать мощь этой функции, приведём отрывок кода из официальной документации:
def run_user_code(envdir):
source = input(">>> ")
try:
# Выполнение введенного кода с клавиатуры
exec(source, envdir)
except Exception as e:
print("Exception in user code:")
print("-"*60)
print(str(e))
print("-"*60)
# словарь для хранения введенных переменных
envdir = {}
while True:
run_user_code(envdir)
# Вывод:
>>> переменная = 2
>>> вторая_переменная = 3
>>> print('сумма переменных равна:', переменная + вторая_переменная)
сумма переменных равна: 5
>>> 1 / 0
Exception in user code:
------------------------------------------------------------
division by zero
------------------------------------------------------------
>>>
Практическая работа
- Напишите программу, которая запрашивала бы у пользователя его данные: его имя, отчество и фамилию. После этого выводила бы строку:
«Здравствуйте, < фамилия > < имя > < отчество >
- Напишите программу, которая предлагала бы пользователю решить пример 666 * 333 // 54. Потом выводила бы на экран правильный ответ и ответ пользователя.
- Запросите у пользователя три числа и два арифметических знака. Выведите результат последовательного выполнения данных операций.
Добрый день!
Нужен решат однородный массив в Питоне:
Дана элементов массив А= [2.3, 5, 8, 12, 1.2] действительный число. Сложит этих чисел. Но надо вводит каждой элемента с помощью функции input. А задача надо решат с использование оператора цикла с параметром, то ест for.
Здравствуйте. Если я правильно понял условия, то решение такое:
A = []
for i in range(5):
A.append(float(input()))
print(‘Сумма введённых чисел:’)
print(sum(A))
# Вывод:
2.3
5
8
12
1.2
Сумма введённых чисел:
28.5