Лог №1
Итак, мы изучаем язык Python3 (на этом компьютере реализация версии 3.4.1). Ещё бывает язык Python2, его предшественник, в нём немного хуже обстоят дела с кодировками, а в остальном они друг на друга очень похожи.
Здесь приведено много диалогов с питоном. >>> является вопросом питона к нам, который на русский можно перевести так: "что изволите приказать?". Языком питона называется то, что мы говорим питону в ответ на этот вопрос. То есть сам символ >>> к языку питона не имеет никакого отношения.
Питон очень прост. Его можно использовать как калькулятор:
abs – от слов absolute value – модуль.
Пробелы можно ставить или не ставить по вкусу: питону нужны пробелы только там, где без них сливаются слова (см. ниже примеры с and и or). Лишние пробелы (там, где они не вносят непонятности) питон игнорирует.
Но если мы его просим сделать что-то, что мы и сами не понимаем, что значит, то он может нам сказать, что и он не понял:
Деление у питона делает то, что мы и хотим. Ещё есть целочисленное деление (оно отбрасывает дробную часть) и остаток от деления. Операция возведения в степень в питоне неожиданно обозначается **. (Символ ^ в питоне занят на очень экзотическую и почти никому не нужную операцию "побитовое-исключющее-или").
Ещё мы можем питону задавать разные вопросы и смотреть, что он ответит: правда или неправда?
Одно важное замечание: когда мы хотим спросить правда ли, что a == b, нужно всегда писать двойной знак равенства. Одинарный знак равенства имеет совсем другой смысл (об этом дальше). Эта традиция пришла из языка C, но сейчас закрепилась в очень многих языках.
Питон разрешает в дробных числах не писать ноль перед десятичной точкой.
Чтобы научиться извлекать корень, у нас есть два варианта. Первый: вспомнить, что извлечение корня есть ничто иное, как возведение в дробную степень:
Второй – воспользоваться функцией извлечения корня.
В питоне несколько тысяч (а может и десятков тысяч) полезных функций есть сразу, и ещё тучу всего в него можно скачать и добавить. Чтобы не запутаться в этом море, оно разделено на кусочки, которые называются модулями.
Чтобы воспользоваться модулем, его нужно проимпортировать, и тогда мы сможем из него брать функции словами имя_модуля.имя_функции:
В модуле math обитает всё, что нужно для тригонометрии. Функция atan2(x,y) делает то же, что и atan(x/y), но при этом, во-первых, корректно обрабатывает случай y == 0, а во-вторых, правильно учитывает знаки x и y, чтобы вернуть величину угла от оси OX до точки, заданной координатами (x,y).1
Есть и другие способы импортировать функции из модуля так, чтобы не писать всякий раз имя модуля:
from что-нибудь import * будет в рамках нашего курса запрещён к употреблению в программах. Дело в том, что если вы так проимпортируете два модуля, то вы уже лишаетесь чёткой уверенности о том, что откуда пришло (пока не прочитаете _полностью_ всю документацию по обоим). Но, на самом деле, даже и с одним модулем так делать не стоит: обычно в программе в один взгляд или в один поиск по тексту файла можно понять, откуда к нам пришло какое-нибудь имя. А в случае from ... import * единственный способ остаётся в том, чтобы пролистать всю программу и заодно прочитать всю документацию на все модули, которые вы так импортируете. Поначалу кому-то и это может оказаться сложным, но объём и сложность наших программ будет быстро расти, так что лучше дурную привычку обходить стороной сразу.
Ещё мы можем про модуль попросить хелпы (для этого нужно, чтобы модуль был проимпортирован):
1 >>> import math
2 >>> help(math)
3 Help on built-in module math:
4
5 NAME
6 math
7
8 DESCRIPTION
9 This module is always available. It provides access to the
10 mathematical functions defined by the C standard.
11
12 FUNCTIONS
13 acos(...)
14 acos(x)
15
16 Return the arc cosine (measured in radians) of x.
17
18 acosh(...)
19 acosh(x)
20
21 Return the hyperbolic arc cosine (measured in radians) of x.
22
23 asin(...)
24 asin(x)
25
26 Return the arc sine (measured in radians) of x.
27
28 asinh(...)
29 asinh(x)
30
31 Return the hyperbolic arc sine (measured in radians) of x.
32
33 atan(...)
34 atan(x)
35
36 Return the arc tangent (measured in radians) of x.
37
38 atan2(...)
39 atan2(y, x)
40
41 Return the arc tangent (measured in radians) of y/x.
42 Unlike atan(y/x), the signs of both x and y are considered.
43
44 atanh(...)
45 atanh(x)
46
47 Return the hyperbolic arc tangent (measured in radians) of x.
48
49 ceil(...)
50 ceil(x)
51
52 Return the ceiling of x as an int.
53 This is the smallest integral value >= x.
54
55 copysign(...)
56 copysign(x, y)
57
58 Return a float with the magnitude (absolute value) of x but the sign
59 of y. On platforms that support signed zeros, copysign(1.0, -0.0)
60 returns -1.0.
61
62 cos(...)
63 cos(x)
64
65 Return the cosine of x (measured in radians).
66
67 cosh(...)
68 cosh(x)
69
70 Return the hyperbolic cosine of x.
71
72 degrees(...)
73 degrees(x)
74
75 Convert angle x from radians to degrees.
76
77 erf(...)
78 erf(x)
79
80 Error function at x.
81
82 erfc(...)
83 erfc(x)
84
85 Complementary error function at x.
86
87 exp(...)
88 exp(x)
89
90 Return e raised to the power of x.
91
92 expm1(...)
93 expm1(x)
94
95 Return exp(x)-1.
96 This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x.
97
98 fabs(...)
99 fabs(x)
100
101 Return the absolute value of the float x.
102
103 factorial(...)
104 factorial(x) -> Integral
105
106 Find x!. Raise a ValueError if x is negative or non-integral.
107
108 floor(...)
109 floor(x)
110
111 Return the floor of x as an int.
112 This is the largest integral value <= x.
113
114 fmod(...)
115 fmod(x, y)
116
117 Return fmod(x, y), according to platform C. x % y may differ.
118
119 frexp(...)
120 frexp(x)
121
122 Return the mantissa and exponent of x, as pair (m, e).
123 m is a float and e is an int, such that x = m * 2.**e.
124 If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0.
125
126 fsum(...)
127 fsum(iterable)
128
129 Return an accurate floating point sum of values in the iterable.
130 Assumes IEEE-754 floating point arithmetic.
131
132 gamma(...)
133 gamma(x)
134
135 Gamma function at x.
136
137 hypot(...)
138 hypot(x, y)
139
140 Return the Euclidean distance, sqrt(x*x + y*y).
141
142 isfinite(...)
143 isfinite(x) -> bool
144
145 Return True if x is neither an infinity nor a NaN, and False otherwise.
146
147 isinf(...)
148 isinf(x) -> bool
149
150 Return True if x is a positive or negative infinity, and False otherwise.
151
152 isnan(...)
153 isnan(x) -> bool
154
155 Return True if x is a NaN (not a number), and False otherwise.
156
157 ldexp(...)
158 ldexp(x, i)
159
160 Return x * (2**i).
161
162 lgamma(...)
163 lgamma(x)
164
165 Natural logarithm of absolute value of Gamma function at x.
166
167 log(...)
168 log(x[, base])
169
170 Return the logarithm of x to the given base.
171 If the base not specified, returns the natural logarithm (base e) of x.
172
173 log10(...)
174 log10(x)
175
176 Return the base 10 logarithm of x.
177
178 log1p(...)
179 log1p(x)
180
181 Return the natural logarithm of 1+x (base e).
182 The result is computed in a way which is accurate for x near zero.
183
184 log2(...)
185 log2(x)
186
187 Return the base 2 logarithm of x.
188
189 modf(...)
190 modf(x)
191
192 Return the fractional and integer parts of x. Both results carry the sign
193 of x and are floats.
194
195 pow(...)
196 pow(x, y)
197
198 Return x**y (x to the power of y).
199
200 radians(...)
201 radians(x)
202
203 Convert angle x from degrees to radians.
204
205 sin(...)
206 sin(x)
207
208 Return the sine of x (measured in radians).
209
210 sinh(...)
211 sinh(x)
212
213 Return the hyperbolic sine of x.
214
215 sqrt(...)
216 sqrt(x)
217
218 Return the square root of x.
219
220 tan(...)
221 tan(x)
222
223 Return the tangent of x (measured in radians).
224
225 tanh(...)
226 tanh(x)
227
228 Return the hyperbolic tangent of x.
229
230 trunc(...)
231 trunc(x:Real) -> Integral
232
233 Truncates x to the nearest Integral toward 0. Uses the __trunc__ magic method.
234
235 DATA
236 e = 2.718281828459045
237 pi = 3.141592653589793
238
239 FILE
240 (built-in)
Это ужасно длинно. (К тому же, все они, зачастую в более читаемом виде, есть на сайте: http://docs.python.org в разделе Library reference).
Зато мы можем попросить питон подсказать, что делает какая-то функция или какие ей давать аргументы:
Существенное замечание.
Когда мы хотим о функции что-то просто сказать, мы пишем её без скобок. И именно это всегда значит, что мы он ней просто хотим сказать. (В языке C, да и, кажется, в Pacasl тоже, это называется "ссылка на функцию"). А когда мы хотим функцию к чему-то применить (вызвать) и получить результат, мы всегда должны после её имени ставить скобки – даже если мы не можем функции дать никаких аргументов.
Возвращаясь к вопросам и сравнениям. Мы можем их сочетать операторами "и" и "или", "не":
Не к слову сказать, а на ноль мы делить не можем:
Новое понятие. Переменная. Переменная (слегка утрируя) – это коробочка с именем, куда мы можем положить значение. (Сильно позже мы увидим, что это никакая не коробочка, а скорее что-то в духе бумажки-наклейки с именем).
У питона есть команда "положить значение в переменную". Выглядит она так: "имя_переменной = значение". Здесь знак равенства одинарный. И очень важно, здесь нельзя менять местами имя переменной и значение, всегда то, что справа, кладётся в переменную, имя которой слева. (Это тоже традиция из языка C, впрочем, может и более древняя, тоже очень устойчивая в очень многих языках программирования. В языке Pascal это действие обозначается `имя_переменной := значение`. В отличие от статически-типизованных без вывода типов языков – типа C и Pascal – в питоне нигде никогда не надо – да и невозможно прямым текстом указать, для значений какого типа предназначена переменная).
Теперь мы можем попробовать понять, как питон понимает фразу Юрия Коваля: "опасайтесь лысых и усатых":
Разумеется, мы можем класть в переменные любые значения и результаты вычисления выражений:
Изредка бывает такая ситуация, когда мы хотим, чтобы переменная у нас была в любом случае, а положим ли мы туда значение, мы ещё не решили (ну то есть пока класть туда нечего, может появится, а может и не появится). Для того, чтобы обозначить такую пустоту, мы можем положить в переменную ничто, то есть значение None.
NB. Питон чувствителен как к регистру букв (т.е. маленькие-большие) в именах переменных, так и везде. None и none – это разные вещи. (Второго из них в питоне заготовленного нету).
1 >>> x = None
Но больше всего нам интересно класть в переменные куски текста. (Правильный термин: строки). Для этого их нужно заключать в кавычки. Можно в одинарные, можно в двойные, результат будет идентичный:
Из строк мы хотим уметь брать кусочки по номеру букв.
Тонкость: буквы в строке нумеруются с нуля. Т.е. буква с номером (умное слово – с индексом) 3 – это чевтёртая буква.
Считаем мы, конечно, не в буквах, а в символах, пробел тоже считается за символ. А вот вылезать за пределы строки нам питон не разрешает.
Ещё мы можем указывать кусок строки, который мы хотим вырезать. Тогда мы указываем индекс начала куска и – тонкость – индекс позиции, следующей за концом куска.
Ещё мы строки можем склеивать (умное слово: "конкатенация") и сравнивать, тут ничего неожиданного:
Строки нельзя менять, так что если мы хотим что-то воткнуть в середину строки, нам придётся её разобрать на два кусочка и руками из них потом склеить новую строку:
Ещё в питоне есть группа функций, которые пытаются из чего мы им ни дадим сделать значение соответствующего типа: int (целые числа), float (дробные числа, они же числа с плавающим десятичным разделителем), str (строки), bool (логические значения).
Все они _очень_ стараются:
Но иногда не получается:
Маленький математический оффтопик. Функция int от дробного числа просто отбрасывает дробную часть. Вопрос: как сделать из неё честное округление?
Но вообще-то, в питоне округление есть встроенное (для этого ничего не надо импортировать), которое ещё и более умное, чем наше:
Дробные числа, они же числа с плавающей точкой. Хранятся в памяти как целоечисло*2^целоечисло. Примерно так же, как вас учат писать на физике. (Только тут размер обоих целых чисел при этом ограничен сверху). У них есть ограничение точности в сколько-то знаков после запятой. А ещё для их ввода (да и вывода тоже) есть такой формат: числоEстепень-десятки:
1 >>> float(3)
2 3.0
3 >>> float("3")
4 3.0
5 >>> 3e16
6 3e+16
7 >>> 3e-16
8 3e-16
9 >>> 3e-1
10 0.3
11 >>> 3000000000000000000000000000000000000000000000
12 3000000000000000000000000000000000000000000000
13 >>> float(3000000000000000000000000000000000000000000000)
14 3e+45
15 >>> int(float(3000000000000000000000000000000000000000000000))
16 3000000000000000106184517130664004033968078848
17 >>> 123456789123456789123456789123456789.0
18 1.2345678912345678e+35
19 >>> int(123456789123456789123456789123456789.0)
20 123456789123456784102659645885120512
str делает из всего строку. Он круче японской бензопилы: нет такого объекта в питоне, из которого str не мог бы сделать строку (впрочем, мы такой объект сделать своими руками в какой-то момент сможем):
bool отвечает на вопрос: то, что мне дали, непусто? То есть значение False он выдаст только для 0, "", False, None. А про все остальные значения он ответит True. Мы увидим, что это иногда помогает писать более простые и понятные программы, но пока что просто подивимся:
1 >>> bool(1 == 3)
2 False
3 >>> bool(1)
4 True
5 >>> bool(42)
6 True
7 >>> bool(0)
8 False
9 >>> bool(-1)
10 True
11 >>> bool("")
12 False
13 >>> bool("jkj")
14 True
15 >>> bool(" ")
16 True
17 >>> x = 1
18 >>> bool(x)
19 True
20 >>> x = None
21 >>> bool(x)
22 False
23 >>> x_was_empty = bool(x)
24 >>> bool(False)
25 False
Все логические операции трактуют свои операнды именно с той же точки зрения, как если бы мы их скормили функции bool. Таким образом not оказывается строгим антонимом к bool:
А это странная синтаксическая ошибка, о которой нужно сообщить авторам питона. Согласно стандарту языка оно должно работать:
Obscure offtopic
Если сравнению мы даём две вещи, которые можно привести к числу, то прежде, чем их сравнивать, питон их приводит к числу. Поэтому получается вот такая ахинея:
Even more obscure offtopic
Когда мы пишем цепочку a and b and c and d, питон будет знать ответ в тот самый момент, когда он увидит среди них первый False. И даже не будет пытаться вычислять остальное. Но что ещё более забавно, что и в качестве ответа он выдаст то значение, которое заставило его оборвать мысль:
И аналогично с or. Благодаря этому мы можем писать такие конструкции:
И ещё более такие:
Возвращаемся к строкам.
Мы их можем класть в переменные. Сравнивать. Проверять, есть ли в них подслово. Узнавать их длину:
Нам потребуются две новых сущности.
Определение объект – это что угодно, что можно положить в переменную. (Но не обязательно его туда класть!)
Определение метод объекта – это функция, лежащая внутри объекта, которая знает, внутри какого объекта лежит, и может с ним что-то делать (или что-то про него говорить).
Пишется это так: объект.метод (собственно, так же, как мы доставали функции из модуля. На самом деле, когда мы говорим import this, у нас появляется объект this, у которого есть куча методов – всё содержимое модуля).
Если путаете слова "метод" и "функция", лучше всегда говорите "функция", ибо это правда.
1 >>> who.count("o")
2 1
3 >>> who.find("o")
4 1
5 >>> "hello".count("l")
6 2
7 >>> "hello".find("o")
8 4
9 >>> "hellooooo".find("o")
10 4
11 >>> n = "hellooooo".find("o")
12 >>> "hellooooo"[n]
13 'o'
14 >>> n
15 4
16 >>> help(who.find)
17 Help on built-in function find:
18
19 find(...) method of builtins.str instance
20 S.find(sub[, start[, end]]) -> int
21
22 Return the lowest index in S where substring sub is found,
23 such that sub is contained within S[start:end]. Optional
24 arguments start and end are interpreted as in slice notation.
25
26 Return -1 on failure.
27
28 >>> "hellooooo".find("o", 4)
29 4
30 >>> "hellolololo".find("o", 4)
31 4
32 >>> "hellolololo".find("o", 5)
33 6
34 >>> "hellolololo".find("o", 5, 6)
35 -1
36 >>> "hellolololo".replace("l", "_")
37 'he__o_o_o_o'
38 >>> "hellolololo".replace("ll", "")
39 'heolololo'
40 >>> word = "HeLlLo"
41 >>> word.lower()
42 'helllo'
43 >>> help(word.lower)
44 Help on built-in function lower:
45
46 lower(...) method of builtins.str instance
47 S.lower() -> str
48
49 Return a copy of the string S converted to lowercase.
50
51 >>> word.upper()
52 'HELLLO'
53 >>> word.capitalize()
54 'Helllo'
55 >>> "heLLO, wUNderful, wolrd!".title()
56 'Hello, Wunderful, Wolrd!'
57 >>> "привет прекрасный мир!".title()
58 'Привет Прекрасный Мир!'
59 >>> "привет прекрасный мир!".capitalize()
60 'Привет прекрасный мир!'
61 >>> "привет ПРЕКРАСНЫЙ мир!".capitalize()
62 'Привет прекрасный мир!'
Нас у строк интересуют методы:
count – количество вхождений подстроки в строку
find – индекс начала первого вхождения подстроки в строку (на самом деле, мы почти никогда этим методом пользоваться не будем)
lower, upper, title, capitalize – меняют регистр букв на маленькие, большие, как в американских заголовках (каждое слово начинается с большой), как в наших заголовках (первая заглавная, остальные маленькие).
replace – возвращает строку, в которой все вхождения данной подстроки заменены на другую
Питон нам не прощает, если мы пытаемся из объекта взять метод, которого в нём нет:
Метод format у строк воспринимает строку как шаблон, в котором парами фигурных скобок обозначены места, куда мы хотим подставлять значения:
Нам никто не мешает сложить несколько преобразований строки в цепочку:
Для чисел format позволяет указывать после символа :, который обозначает, что мы хотим вывести значение как-то по-особому:
- количество символов, которые мы отводим под это число (если не влезет, то расширим)
. количество символов после запятой, которые мы хотим видеть (всегда обрезаем до такого или меньше)
Ещё format позволяет нам в фигурных скобках указывать номер значния, которое мы хотим сюда подставить. Это очень удобно, если мы хотим подставлять больше одного значения или одно значение больше одного раза, или хотим что-то переставлять:
Итого, шаблон для подстановки выглядит так:
{
- необязательно номер аргумента
необязательно :, после которого:
- необязательно минимальная длина
необязательно . количество знаков после запятой
}
Суть примера про atan2 скорее даже не в том, чтобы поговорить о тригонометрии, а в том, чтобы показать степень заботы о нас у питона. (1)