## page was renamed from Main/Python/2009/2008/Lesson01
## page was renamed from Main/Python/2008/Lesson01
## page was renamed from Courses/Python/Lesson01
== Занятие 1. ==
Краткое содержание:
Вводные слова. Питон как калькулятор (числа, строки, списки). Поиск документации по языку (dir, help, pydoc, сайты). Простейшая работа с файлами.
----
<<TableOfContents>>

=== План рассказа ===
 * Введение:
  1. кто такой BDFL = Benevolent Dictator for Life = Guido Van Rossum = дяденька Гвидо = автор языка
  2. всё на самом деле очень просто; один из главных принципов языка -- принцип наименьшей неожиданности
  3. python way (сегодня: "batteries included" + "помощь где-то рядом" + "я не знаю, как это делать, но угадаю с первой попытки")
 * Простые примеры:
  * Стрелочки ({{{>>>}}}) обозначают приглашение командной строки интерпретатора. Мы пишем их в примерах и их нужно писать в ответах на задания.
  *. {{{#!python
>>> print "hello, world"
hello, world
>>> print 2*2
4
>>> print 1+2
3
>>> print "This page has", 2*5, "lines"
This page has 10 lines
>>> a = "one" # переменные создаются в момент упоминания
>>> print a
one
>>> a = "one" + "word" # склейка строк (умное слово: конкатенация)
>>> print a, 2, "words"
oneword 2 words
>>> a = "Hello, world"; print a # несколько операторов можно писать через точку с запятой
>>> a = [1, 2, 3] # список из трёх чисел
>>> print a[0] # получение элемента списка, нумерация с ноля (древняя программистская традиция)
1
>>> print a[0:2] # получение куска списка (умное слово: slice / slicing)
[1, 2]
>>> print a[1:2] # NB: эта операция похожа на математичекий интервал [1,2) -- правый конец не включён в интервал
[2]
>>> print a[-1] # приятное удобство: отрицательные числа дают нумерацию с конца, начиная с -1
[3]
>>> a = [1, "hello", [2,3]] # в списки можно сваливать значения любых типов
>>> print a[:2]
[1, "hello"]
>>> print a[1:-1] # начиная со втрого элемента, до последнего, иключая его
["hello"]
>>> print a[-1][0] # внутри списка список, его тоже можно сразу индексировать
2
>>> a = "hello"
>>> print a[2:4] # строки похожи на списки
"ll"
>>> print a[0] # NB: любой элемент строки -- как бы тоже строка; или можно считать, это это не индексация (получение элемента по номеру), а тоже вырезка -- кому как удобнее
"h"
>>> print 1+1j # комплексные числа
(1+1j)
>>> print (1+1j) * 1j
(-1+1j)
>>> print 1.0 + 1 # числа с плавающей точкой
2.0
>>> 1234567891011 # очень большие целые числа выводятся с буквой L на конце
1234567891011L
>>> a = "hello, world" # что строка в кавычках, что переменная a указывают на объект типа "строка"
>>> print a.title() # у объектов можно вызывать методы
Hello, world
>>> print a # данный метод не изменил объект, но некоторые методы меняют
hello, world
>>> a # в интерпретаторе мы можем опускать слово print, тогда нам выдадут более информативное представление объекта, но в программах такой приём не работет
"hello, world"
}}}

 * Нудятина про типы:
  *. {{{#!python
>>> type(1) # функция type возвращает тип объекта
<type 'int'>
>>> type(1.0)
<type 'float'>
>>> type(12345678910)
<type 'long'>
>>> type("hello")
<type 'str'>
>>> type(1+1j)
<type 'complex'>
>>> type([])
<type 'list'>
>>> type(1) == int # тип объекта -- это такой объект
True
>>> type(int) # тип объекта -- это объект типа "тип" :)
<type 'type'>
>>> a = "123"
>>> print a + "1" # это ещё конкатенация строк
1231
>>> print int(a) + 1 # это приведение типов, довольно умное: получили из строки число
124
>>> print list([1,2,3]) # list -- объект типа, он же сам тип, он же класс, он же конструктор типа; в данном случае мы его используем как конструктор типа -- функция, которая, если ей дать какие-то (осмысленные) аргументы, вернёт объект этого типа
[1, 2, 3]
}}}
  * Пара слов об утиной типизации. Основной постулат: то, что ходит как утка и крякает как утка, и есть утка. (Здесь: если вы не уверены абсолютно точно, что нужен какой-то конкретный тип, не надо делать приведение типов).
  . Как из числа сделать строку? Что делает {{{list("hello")}}}?
 * Форматирование строк операцией {{{%}}}: {{{#!python
>>> a = "This %s is very %s"
>>> b = ("loaf", "tasty") # в скобках через запятую -- кортеж (tuple) -- почти то же самое, что список
>>> c = a % b # для целых чисел % -- взятие остатка от деления; для строк -- подстановка формата как в printf, sprintf и иже с ними
>>> print a, b, "==>", c
This %s is very %s ("loaf", "tasty") ==> This loaf is very tasty
>>> print "Total %02d%%" % (1,) # кортеж из одного элемента требует некрасивой запятой в конце, чтобы отличаться от пары скобок; операция % поддерживает все возможности форматирования printf, например дополнение чисел нулями до нужного количества разрядов; символ % в строках нужно удваивать, чтобы отличать от элемента шаблона
Total 01%
}}}
 * Подсказки
  1. Как узнать что-то об объекте a? (Пусть у нас есть объект a, о котором мы ничего не знаем; как узнать?) {{{#!python
>>> a # можно попытаться распечатать этот объект, этой информации может хватить
<type 'int'>
>>> help(a) # выдаст большую подсказку, в Linux через программу less. Важные клавиши, которые в ней нужно знать: выход -- q, вверх-вниз как обычно, поиск: /слово

>>> dir(a) # выдаёт список имён полей объекта (методов, свойств, переменных, как их не назови: всё, что внутри объекта)

>>> help(str.title) # подсказка по методу строки; NB: эта подсказка относится к примеру a = "hello, world"; print a.title()

>>> help(str) # свод всех методов строки (NB: str -- это тот же объект, что и type("hello"), например)

>>> help() # если вы случайно забыли дать аргумент функции help(), вы попадёте в интерактивный поисковик документации; внимательно прочитайте, что вам написала система; что будет происходить с вами дальше -- ваша личная головная боль, я предупредил
}}}
  2. Вы скачали библиотеку, как о ней что-нибудь узнать? Если в ней есть, например, модуль main.py, можно сказать (из командной строки unix, а не из интерпретатора python):
   * {{{pydoc main}}}, чтобы получить подсказку по всему модулю
   * {{{pydoc main.f}}} -- только по методу f из модуля main
   * {{{pydoc str.title}}} в командной строке unix -- точно то же самое, что и {{{help(str.title)}}} в командной строке python
  3. Две полезные ссылки:
   * http://docs.python.org/lib/lib.html -- если нужно найти модуль по его функциональности или изучить общую идею работы с каким-нибудь классом (на сайте python.org, в уголке слева Documentation, там Library Reference)
   * http://docs.python.org/ref/specialnames.html -- про имена вида {{{__add__}}} (на сайте python.org, Documentation, Language Reference, Special method names... остальное там читать скучно и трудоёмко)
  4. Иногда приходится читать исходные тексты чужих программ. Это не так трудно и помогает учиться новым вещам.
  5. '''Основное правило поиска документации''': если вы ничего о каком-то типе или модуле не знаете и хотите понять, что к чему, открывайте Library Reference (см. п. 3); если вы имеете представление о том, как с объектом работать и хотите вспомнить знакомый метод или посмотреть метод, похожий на знакомый -- используйте {{{help(объект)}}}.
 * Простейшая работа с файлами:
  1. {{{f = open("file")}}} или {{{f = open("file", "w")}}}
  2. {{{f.read()}}} или {{{f.write("hello")}}} или ищите в документации
  3. {{{f.close()}}}

=== Обязательно научиться ===
 * переменные: простое присваивание
 * оператор print
 * простая арифметика
 * арифметика строк
 * что-угодно > строка (str, %)
 * строка > число
 * простая работа с последовательностями: строками, списками и кортежами (slice)
 * сортировка
 * help (+ поиск в less)
 * простая работа с файлами

=== Задания ===
Все задания выполняются в интерактивном режиме интерпретатора.

Для результатов задания создайте директорию {{{Python}}} в вашей домашней директории. (В windows: {{{H:\Python}}}, в linux: {{{ mkdir ~/Python; cd ~/Python }}}). В качестве результата задания принимается файл {{{practice1.log}}} в директории результатов.  В файл нужно записать те части вашего диалога с интерпретатором, которые приводят к получению результата задания. Например, если бы задание номер 0 было "напечатайте результат умножения 2 на 2", в файл должен был бы попасть такой фрагмент:
{{{
>>> print 2*2
4
}}}

Во избежание головной боли и себе (когда вы на следующий раз обнаружите, что вас нет в таблице результатов первого задания) и мне (когда вы на это пожалуетесь и мне придётся срочно допроверять не пойми что), воспроизводите имена файлов в точности и строго следуйте формату.

Почти все задания в первую очередь нацелены на умение поиска документации. Резонно предположить, что, хотя я что-то и рассказал на вступительной части, в общем, вы имеете очень смутное представление о тех типах, с которыми вам нужно работать. Поэтому лучше начать с использования документации на сайте (см. выше).

 1. Сколько зёрен риса попросил за своё изобретение автор шахмат?
  . Легенда гласит, что после того, как изобретатель шахмат преподнёс своё изобретение шаху и шаху оно понравилось, шах предложил изобретателю попросить любую награду. Автор игры скромно попросил положить на первую клетку шахматной доски 1 зерно, на вторую 2, и на каждую следующую класть вдвое больше зёрен, чем на предыдущую.
  . Математическая часть задания (к программированию отношения не имеет): упростить записть соответсвтующей суммы.
  . Программистская часть задания: научиться возводить числа в степень (а также вообще посмотреть, чего интересного пишут про числа в документации)
 2. Нарисуйте на экране прямоугольник в ASCII-art в 40 символов в ширину. Подберите высоту рамки на ваш вкус. (Из символов -, | для рамок и + в уголках).
  . Подсказка:
   .а) Научитесь делать длинные строки из одинаковых символов
   .б) сохраните во вспомогательную переменную строку из нужного количества "-" между двумя "+"
   .в) сохраните в другюу вспомогательную переменную строку из нужного количества пробелов между двумя "|"
   .г) нарисуйте рамку из этих строк
 3. Нарисуйте в таком же в прямоугольнике число зёрен риса изобретателя шахмат (см. str.ljust, str.rjust, str.center)
  . Если вы выполняли предыдущее упражнение по подсказке, то вам достаточно немного переписать вторую вспомогательную переменную.
 4. Напишите число зёрен риса изобретателя шахмат в более удобочитаемом виде (расставьте пробелы между каждыми тремя символами начиная с конца).
  . Подсказка:
   .а) сохраните в переменную строковое представление числа (как сделать из числа строку?)
   .б) научитесь выводить на экран последние 3 символа строки; 3 символа перед ними, ...
   .в) выпишите (существующие) интервалы строки по три символа через пробел
  . Это задание подразумевает довольно много унылого повторения кода и предположение, что число в длину не больше 20 символов. Вопреки ожиданиям многих, форматирование через % не даёт готового решения в этом случае.
 5. Сохраните интервалы, которые вы выписывали через пробел для предыдущего задания в список. Прочитайте документацию по str.join. Сохраните в переменной строковое представление числа зёрен риса изобретателя шахмат через пробелы, как в предыдущем задании.
 6. Верните всё обратно (превратите строку с читаемым представлением числа зёрен риса изобретателя шахмат в число):
  .а) разбейте строку по пробелам
  .б) соедините получившиеся куски
  .в) превратите в число, распечатайте это число; совпадает ли оно с исходным числом?
  . Можно ли сделать пункты а и б проще?
 7. Откройте файл {{{/etc/passwd}}} (в Windows: {{{P:/SpecialCourses/Python/passwd}}}). В этом файле хранится информация о пользовательских аккаунтах в системе (в данном случае, не о всех). На каждый пользовательский аккаунт в файле отведено по строке, состоящей из семи записей, разделённых двоеточием: логин, буква x<<FootNote("раньше там хранился пароль в зашифрованном виде -- а на самой-самой заре времён и в незашифрованном, -- теперь осталась только одна буква от фразы: хрен взломаешь")>>, числовой идентификатор пользователя, числовой идентификатор группы, имя пользователя, домашняя директория, шелл. Выведите на экран по значение поля "имя пользователя" (5-е поле) для первой и последней записи файла. Посортируйте строки, полученные из файла и снова выведите на экран первое и последнее имя. По шагам:
  .а) откройте файл, прочитайте, разбейте по строкам, сохраните в переменную
  .б) разбейте по символу ":" первую строку, выведите пятый элемент полученного списка
  .в) аналогично для последней строки
  .г) отсортируйте список строк
  .д) повторите б и в
  . Обратите внимание на то, что в файле на самом деле нет пустых строк, но есть пустые имена пользователей.
  . Подсказка: В традиции unix принято завершать файл символом переноса строки. Это должно создать для вас определённые трудности.
 8. (*) Выведите название 3-й последовательности из файла /home/export/samba/public/SpecialCourses/Python/file.fasta (в Windows: P:/SpecialCourses/Python/file.fasta). Сохраните эту последовательность в формате fasta в файл file.fasta в директории результатов задания.
 9. (**) Следующая строка зашифрована кодом Цезаря с параметром 13. Расшифруйте её: ''Ybbxf yvxr lbh unir fhpprffshyyl qrpbqrq guvf fragrapr. Pbatenghyngvbaf urer. V whfg jbaqre vs lbh znantrq gb ybbx hc qbpf sbe rapbqr zrgubq bs fge.''
  . Если вы не знаете, каким кодом шифровал Гай Юлий Цезарь свои секретные тексты, поищите в интернете.
  . Подсказка: это задание можно выполнить вызовом одного метода. Но есть и более сложный путь, который начинается так: {{{#!python
>>> import string
>>> help(string.maketrans)
}}}