<commit_before>{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "toc": true
   },
   "source": [
    "<h1>Содержание<span class=\"tocSkip\"></span></h1>\n",
    "<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#Ввод-двух-чисел-из-одной-строки\" data-toc-modified-id=\"Ввод-двух-чисел-из-одной-строки-1\">Ввод двух чисел из одной строки</a></span></li><li><span><a href=\"#Ввод-списка-чисел-из-одной-строки\" data-toc-modified-id=\"Ввод-списка-чисел-из-одной-строки-2\">Ввод списка чисел из одной строки</a></span></li><li><span><a href=\"#Форматированный-вывод\" data-toc-modified-id=\"Форматированный-вывод-3\">Форматированный вывод</a></span></li></ul></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Продвинутый ввод-вывод"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ввод двух чисел из одной строки"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Как вы могли заметить, мы так и не научились считывать два числа из одной строки. Это одна из немногих вещей, которая в Python чуть-чуть сложнее, чем в более привычных языках."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2\n",
      "1 <class 'int'>\n",
      "2 <class 'int'>\n"
     ]
    }
   ],
   "source": [
    "a, b = map(int, input().split())  # Так считываются 2 целых числа из одной строки\n",
    "print(a, type(a))\n",
    "print(b, type(b))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Что происходит при выполнении этого кода:\n",
    "\n",
    "1. Вызывается функция `input` и считывается одна строка.\n",
    "1. Для считанной строки вызывается метод `split`, разбивает ее по пробелам и возвращает список полученных строк. Наши числа как раз и были записаны через пробел.\n",
    "1. Функция `map` делает новый «список», применяя функцию `int` (первый аргумент) к каждому элементу списка строк (второй аргумент). В результате получается «список» целых чисел. Слово «список» в кавычках, потому что на самом деле `map` возращает не список, объект типа `map`, который ведёт себя похожим на список образом.\n",
    "1. Происходит параллельное присваивание: переменной `a` присваивается значение первого числа в списке, переменной `b` значение второго числа.\n",
    "\n",
    "Давайте ниже напишем эквивалент этого кода, только без генератора списка. Так писать не нужно, потому что это медленно и на самом деле сложнее."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3 5\n",
      "['3', '5']\n",
      "3 <class 'int'>\n",
      "5 <class 'int'>\n"
     ]
    }
   ],
   "source": [
    "# input()\n",
    "s = input()\n",
    "\n",
    "# input().split()\n",
    "words = s.split()\n",
    "print(words)\n",
    "\n",
    "# map(int, input().split())\n",
    "numbers = []\n",
    "for word in words:\n",
    "    numbers.append(int(word))\n",
    "\n",
    "# a, b = map(int, input().split())\n",
    "a, b = numbers\n",
    "\n",
    "print(a, type(a))\n",
    "print(b, type(b))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ввод списка чисел из одной строки"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ровно таким же способов из строки считывается сколько угодно чисел. При этом надо преобразовать результат функции `map` в список `list`. Например, найдём минимум из чисел, заданных в одной строке через пробелы:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 -3 6\n",
      "-3\n"
     ]
    }
   ],
   "source": [
    "numbers = list(map(int, input().split()))\n",
    "print(min(numbers))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Метод `strip`, применяемый к строке, убирает вокруг неё лишние пробельные символы. Строки с пробельными символами в начале или в конце строки вполне могут оказаться на входе вашей программы:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['sdf', 'kjk', 'sd']\n",
      "['', '', '', 'sdf', 'kjk', '', '', 'sd', '', '', '']\n",
      "\n",
      "sdf kjk   sd\n",
      "['sdf', 'kjk', '', '', 'sd']\n"
     ]
    }
   ],
   "source": [
    "s = \"   sdf kjk   sd   \"\n",
    "print(s.split())  # split без параметров умеет разбивать по нескольким пробелам\n",
    "print(s.split(' '))\n",
    "print()\n",
    "\n",
    "s = s.strip()\n",
    "print(s)\n",
    "print(s.split(' '))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Форматированный вывод"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "print и его аргументы"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3<commit_msg>Advanced IO<commit_after>{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "toc": true
   },
   "source": [
    "<h1>Содержание<span class=\"tocSkip\"></span></h1>\n",
    "<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#Ввод\" data-toc-modified-id=\"Ввод-1\">Ввод</a></span><ul class=\"toc-item\"><li><span><a href=\"#Ввод-списка--слов-из-одной-строки\" data-toc-modified-id=\"Ввод-списка--слов-из-одной-строки-1.1\">Ввод списка  слов из одной строки</a></span></li><li><span><a href=\"#Ввод-списка-чисел-из-одной-строки\" data-toc-modified-id=\"Ввод-списка-чисел-из-одной-строки-1.2\">Ввод списка чисел из одной строки</a></span></li><li><span><a href=\"#Ввод-двух-чисел-из-одной-строки\" data-toc-modified-id=\"Ввод-двух-чисел-из-одной-строки-1.3\">Ввод двух чисел из одной строки</a></span></li></ul></li><li><span><a href=\"#Вывод\" data-toc-modified-id=\"Вывод-2\">Вывод</a></span><ul class=\"toc-item\"><li><span><a href=\"#Аргументы-функции-print\" data-toc-modified-id=\"Аргументы-функции-print-2.1\">Аргументы функции <code>print</code></a></span></li><li><span><a href=\"#Вывод-многих-значений-в-одной-строке\" data-toc-modified-id=\"Вывод-многих-значений-в-одной-строке-2.2\">Вывод многих значений в одной строке</a></span></li></ul></li></ul></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Продвинутый ввод-вывод"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ввод"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Ввод списка  слов из одной строки"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python позволяет считывать с помощью функции `input()` только всю строку целиком до следующего перевода строки.\n",
    "\n",
    "\n",
    "Но что делать, если мы хотим считать несколько значений из одной строки? В этом нам поможет метод `split()`. Давайте напишем программу, которая считывает несколько слов из одной строки и выводит их в обратном порядке:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "one two three\n",
      "three\n",
      "two\n",
      "one\n"
     ]
    }
   ],
   "source": [
    "words = input().split()\n",
    "words.reverse()\n",
    "\n",
    "# Пока выводим по одному слову в строке. Скоро научимся выводить сразу много слов в одной строке.\n",
    "for word in words:\n",
    "    print(word)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "То же самое более подробно:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "one two three\n",
      "Строка: \"one two three\"\n",
      "Список отдельных слов: ['one', 'two', 'three']\n",
      "Перевёрнутый список слов: ['three', 'two', 'one']\n",
      "three\n",
      "two\n",
      "one\n"
     ]
    }
   ],
   "source": [
    "# Считываем одну строку с клавиатуры. Она содержит все символы, включая пробелы.\n",
    "line = input()\n",
    "print('Строка: \"' + line + '\"')\n",
    "\n",
    "# Разбиваем строку по пробельным символам и получаем список слов\n",
    "words = line.split()\n",
    "print('Список отдельных слов:', words)\n",
    "\n",
    "# Переворачиваем список слов\n",
    "words.reverse()\n",
    "print('Перевёрнутый список слов:', words)\n",
    "\n",
    "# Проходим по всем словам из списка и выводим каждое\n",
    "for word in words:\n",
    "    print(word)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Частая ошибка** — забыть скобки после `input`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "'function' object has no attribute 'split'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-12-c2a025ff0009>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mline\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msplit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m: 'function' object has no attribute 'split'"
     ]
    }
   ],
   "source": [
    "line = input.split()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ошибка переводиться с английского как `ОшибкаАтрибута: У объекта типа 'функция' нет атрибута 'split'`.\n",
    "\n",
    "Так происходит потому что:\n",
    "\n",
    "- `input` — это объект-функция (тип `function`)\n",
    "- `input()` — это вызов функции, который возращает строку (тип `str`)\n",
    "- У объектов типа `str` (строк) определён метод `split`, а у объектов типа `function` (функций) — нет\n",
    "- Мы попытались вызвать метод `split` у объекта типа `function`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Похожая проблема произойдёт если забыть скобки после `split`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Ввод списка чисел из одной строки"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Чтобы считать одно число из строки, нам приходилось преобразовывать результат функции `input()` к целому числу (`int(input())`), потому что `input()` возращает строку (`str`).\n",
    "\n",
    "`input().split()` возращает список строк. Если мы хотим получить список чисел, то нам надо преобразовать каждую из этих строк в число. Самый прямолинейный способ это сделать — используя цикл:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2018 42 3\n",
      "Числа: [2018, 42, 3]\n"
     ]
    }
   ],
   "source": [
    "words = input().split()\n",
    "\n",
    "# Преобразуем строки в числа\n",
    "numbers = []\n",
    "for word in words:\n",
    "    numbers.append(int(word))\n",
    "\n",
    "print(\"Числа:\", numbers)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Обратите внимание на отсутствие кавычек вокруг элементов списка. Это значит, что у нас там числа, а не строки."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Но Python позволяет сделать то же самое **короче и эффективнее**, использовав немного чёрной магии:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2018 42 3\n",
      "Числа: [2018, 42, 3]\n"
     ]
    }
   ],
   "source": [
    "# Такое считывание работает быстрее, чем предыдущий пример\n",
    "numbers = list(map(int, input().split()))\n",
    "print(\"Числа:\", numbers)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Функция `map(func, lst)` возращает «список», полученный применением функции `func` к каждому элементу списка `lst`.\n",
    "\n",
    "Мы взяли «список» в кавычки, потому что это не совсем список, а объект типа `map`, который иногда ведёт себя также как список, а иногда — нет. Поэтому мы явно преобразуем результат в полноценный список (`list`)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Ввод двух чисел из одной строки"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Для этого надо считать список чисел и сделать параллельное присваивание:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3 5\n",
      "3 <class 'int'>\n",
      "5 <class 'int'>\n"
     ]
    }
   ],
   "source": [
    "# Обратите внимание на отсутствие преобразования в список. Здесь в нём нет необходимости.\n",
    "a, b = map(int, input().split())\n",
    "print(a, type(a))\n",
    "print(b, type(b))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Аналогично можно ввести три числа:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5 8 13\n",
      "5 <class 'int'>\n",
      "8 <class 'int'>\n",
      "13 <class 'int'>\n"
     ]
    }
   ],
   "source": [
    "# Обратите внимание на отсутствие преобразования в список. Здесь в нём нет необходимости.\n",
    "a, b, c = map(int, input().split())\n",
    "print(a, type(a))\n",
    "print(b, type(b))\n",
    "print(c, type(c))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Или две строки:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Дональд Кнут\n",
      "Дональд <class 'str'>\n",
      "Кнут <class 'str'>\n"
     ]
    }
   ],
   "source": [
    "first_name, last_name = input().split()\n",
    "print(first_name, type(first_name))\n",
    "print(last_name, type(last_name))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Вывод"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Аргументы функции `print`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Как вы уже знаете, функция `print` принимает сколько угодно значений и выводит их через пробел. Но у неё есть два дополнительных аргумента:\n",
    "\n",
    "- `sep` — что выводить между значениями. По умолчанию `\" \"` (пробел). От английского separator — разделитель.\n",
    "- `end` — что выводить после последнего значениями. По умолчанию `\"\\n\"` (перевод строки).\n",
    "\n",
    "Задаются они в конце после всех аргументов:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5.07.2018\n"
     ]
    }
   ],
   "source": [
    "day, month, year = '5', '07', '2018'\n",
    "# День месяц и год выводятся через точку, а не через пробел\n",
    "print(day, month, year, sep='.')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "This is Sparta!!!"
     ]
    }
   ],
   "source": [
    "# В конце вывелись три восклецательных знака. Между \"Sparta\" и \"!!!\" нет пробела.\n",
    "print(\"This\", \"is\", \"Sparta\", end=\"!!!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 1 2 3 5 8 13 21 \n"
     ]
    }
   ],
   "source": [
    "# Выводим список чисел в одну строку\n",
    "for x in [1, 1, 2, 3, 5, 8, 13, 21]:\n",
    "    # Заменяем end на пробел, чтобы продолжать выводить в той же строке\n",
    "    print(x, end=\" \")\n",
    "# Выводим первод строки в конце\n",
    "print()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Вывод многих значений в одной строке"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Выше показан способ это сделать, но он слишком многословен. Того же самого можно добиться так:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 1 2 3 5 8 13 21\n"
     ]
    }
   ],
   "source": [
    "numbers = [1, 1, 2, 3, 5, 8, 13, 21]\n",
    "print(*numbers)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`print(*lst)` — это то же самое, что и передать все элементы списка функции: `print(lst[0], lst[1], ..., lst[len(lst) - 1])`."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
{'fraction_non_alphanumeric': 0.20760344921091164, 'fraction_numerical': 0.017896849069906177, 'mean_word_length': 2.5805825242718448, 'pattern_counts': {'":': 269, '<': 98, '<?xml version=': 0, '>': 99, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7295181', 'n_tokens_mistral': 7978, 'n_tokens_neox': 8297, 'n_words': 1586}