summaryrefslogtreecommitdiffhomepage
path: root/ru-ru
diff options
context:
space:
mode:
Diffstat (limited to 'ru-ru')
-rw-r--r--ru-ru/c-ru.html.markdown2
-rw-r--r--ru-ru/forth-ru.html.markdown3
-rw-r--r--ru-ru/nim-ru.html.markdown254
-rw-r--r--ru-ru/pascal-ru.html.markdown217
-rw-r--r--ru-ru/perl-ru.html.markdown30
-rw-r--r--ru-ru/python-ru.html.markdown963
-rw-r--r--ru-ru/ruby-ru.html.markdown2
7 files changed, 1051 insertions, 420 deletions
diff --git a/ru-ru/c-ru.html.markdown b/ru-ru/c-ru.html.markdown
index ba3c19ee..cc68d620 100644
--- a/ru-ru/c-ru.html.markdown
+++ b/ru-ru/c-ru.html.markdown
@@ -353,7 +353,7 @@ int main() {
// Это не работает, если строка является массивом
// (потенциально задаваемой с помощью строкового литерала)
- // который находиться в перезаписываемой части памяти:
+ // который находится в перезаписываемой части памяти:
char foo[] = "foo";
foo[0] = 'a'; // это выполнится и строка теперь "aoo"
diff --git a/ru-ru/forth-ru.html.markdown b/ru-ru/forth-ru.html.markdown
index 05316578..2fc4ad7c 100644
--- a/ru-ru/forth-ru.html.markdown
+++ b/ru-ru/forth-ru.html.markdown
@@ -12,9 +12,10 @@ lang: ru-ru
Внимание: эта материал использует реализацию Форта - Gforth, но большая часть написанного будет работать в других средах.
+
```
\ Это комментарий
-( Это тоже комментарий, но использыется для предоределённых слов )
+( Это тоже комментарий, но используется для предоределённых слов )
\ --------------------------------- Прекурсор --------------------------------
diff --git a/ru-ru/nim-ru.html.markdown b/ru-ru/nim-ru.html.markdown
index d05583d7..0e08f1bf 100644
--- a/ru-ru/nim-ru.html.markdown
+++ b/ru-ru/nim-ru.html.markdown
@@ -6,6 +6,7 @@ contributors:
- ["Dennis Felsing", "http://felsin9.de/nnis/"]
translators:
- ["Nomadic", "https://github.com/n0madic"]
+ - ["dvska", "https://github.com/dvska"]
lang: ru-ru
---
@@ -16,25 +17,25 @@ Nim (ранее известный, как Nimrod) — язык программ
Nim эффективный, выразительный и элегантный.
```nim
-var # Объявление (и присваивание) переменных,
- letter: char = 'n' # с указанием типа или без
- lang = "N" & "im"
- nLength : int = len(lang)
+var # Объявление (и присваивание) переменных,
+ буква: char = 'n' # с указанием типа или без
+ язык = "N" & "im"
+ nLength : int = len(язык)
boat: float
- truth: bool = false
+ правда: bool = false
-let # Используйте let *сразу* для объявления и связывания переменных.
- legs = 400 # legs неизменяемый.
- arms = 2_000 # Символ _ игнорируется и удобен для длинных чисел.
- aboutPi = 3.15
+let # Используйте let *сразу* для объявления и связывания переменных.
+ ноги = 400 # ноги неизменяемый.
+ руки = 2_000 # Символ _ игнорируется и удобен для длинных чисел.
+ почтиПи = 3.15
const # Константы вычисляются во время компиляции. Это обеспечивает
debug = true # производительность и полезно в выражениях этапа компиляции.
- compileBadCode = false
+ компилироватьПлохойКод = false
-when compileBadCode: # `when` это `if` этапа компиляции.
- legs = legs + 1 # Эта ошибка никогда не будет скомпилирована.
- const input = readline(stdin) # Значения констант должны быть известны во
+when компилироватьПлохойКод: # `when` это `if` этапа компиляции.
+ ноги = ноги + 1 # Эта ошибка никогда не будет скомпилирована.
+ const ввод = readline(stdin) # Значения констант должны быть известны во
# время компиляции.
discard 1 > 2 # Примечание. Компилятор будет жаловаться, если результат
@@ -52,27 +53,27 @@ discard """
# Кортежи
var
- child: tuple[name: string, age: int] # Кортежи определяют *как* имя поля
- today: tuple[sun: string, temp: float] # так *и* порядок полей.
+ дитя: tuple[имя: string, возраст: int] # Кортежи определяют *как* имя поля
+ сегодня: tuple[солнце: string, температура: float] # так *и* порядок полей.
-child = (name: "Rudiger", age: 2) # Присвоить все сразу литералом ()
-today.sun = "Overcast" # или отдельно по полям.
-today.temp = 70.1
+дитя = (имя: "Rudiger", возраст: 2) # Присвоить все сразу литералом ()
+сегодня.солнце = "Пасмурно" # или отдельно по полям.
+сегодня.температура = 20.1
# Последовательности
var
- drinks: seq[string]
+ напитки: seq[string]
-drinks = @["Water", "Juice", "Chocolate"] # @[V1,..,Vn] является литералом
- # последовательности
+напитки = @["Вода", "Сок", "Какао"] # @[V1,..,Vn] является литералом
+ # последовательности
-drinks.add("Milk")
+напитки.add("Молоко")
-if "Milk" in drinks:
- echo "We have Milk and ", drinks.len - 1, " other drinks"
+if "Молоко" in напитки:
+ echo "У нас тут Молоко и ещё", напитки.len - 1, " напиток(ов)"
-let myDrink = drinks[2]
+let мойНапиток = напитки[2]
#
# Определение типов
@@ -82,30 +83,30 @@ let myDrink = drinks[2]
# Это то, что делает статическую типизацию мощной и полезной.
type
- Name = string # Псевдоним типа дает вам новый тип, который равнозначен
- Age = int # старому типу, но более нагляден.
- Person = tuple[name: Name, age: Age] # Определение структур данных.
- AnotherSyntax = tuple
+ Имя = string # Псевдоним типа дает вам новый тип, который равнозначен
+ Возраст = int # старому типу, но более нагляден.
+ Человек = tuple[имя: Имя, возраст: Возраст] # Определение структур данных.
+ АльтернативныйСинтаксис = tuple
fieldOne: string
secondField: int
var
- john: Person = (name: "John B.", age: 17)
- newage: int = 18 # Было бы лучше использовать Age, чем int
+ джон: Человек = (имя: "John B.", возраст: 17)
+ новыйВозраст: int = 18 # Было бы лучше использовать Возраст, чем int
-john.age = newage # Но это все же работает, потому что int и Age синонимы.
+джон.возраст = новыйВозраст # Но это все же работает, потому что int и Возраст синонимы.
type
- Cash = distinct int # `distinct` делает новый тип несовместимым с его
- Desc = distinct string # базовым типом.
+ Нал = distinct int # `distinct` делает новый тип несовместимым с его
+ Описание = distinct string # базовым типом.
var
- money: Cash = 100.Cash # `.Cash` преобразует int в наш тип
- description: Desc = "Interesting".Desc
+ money: Нал = 100.Нал # `.Нал` преобразует int в наш тип
+ описание: Описание = "Interesting".Описание
-when compileBadCode:
- john.age = money # Error! age is of type int and money is Cash
- john.name = description # Компилятор говорит: "Нельзя!"
+when компилироватьПлохойКод:
+ джон.возраст = money # Error! возраст is of type int and money is Нал
+ джон.имя = описание # Компилятор говорит: "Нельзя!"
#
# Дополнительные типы и структуры данных
@@ -114,50 +115,50 @@ when compileBadCode:
# Перечисления позволяют типу иметь одно из ограниченного числа значений
type
- Color = enum cRed, cBlue, cGreen
- Direction = enum # Альтернативный формат
- dNorth
- dWest
- dEast
- dSouth
+ Цвет = enum цКрасный, цГолубой, цЗеленый
+ Направление = enum # Альтернативный формат
+ нСевер
+ нЗапад
+ нВосток
+ нЮг
var
- orient = dNorth # `orient` имеет тип Direction, со значением `dNorth`
- pixel = cGreen # `pixel` имеет тип Color, со значением `cGreen`
+ напр = нСевер # `напр` имеет тип Направление, со значением `нСевер`
+ точка = цЗеленый # `точка` имеет тип Цвет, со значением `цЗеленый`
-discard dNorth > dEast # Перечисления обычно являются "порядковыми" типами
+discard нСевер > нВосток # Перечисления обычно являются "порядковыми" типами
# Поддиапазоны определяют ограниченный допустимый диапазон
type
- DieFaces = range[1..20] # Допустимым значением являются только int от 1 до 20
+ Кости = range[1..20] # 🎲 Допустимым значением являются только int от 1 до 20
var
- my_roll: DieFaces = 13
+ мой_бросок: Кости = 13
-when compileBadCode:
- my_roll = 23 # Error!
+when компилироватьПлохойКод:
+ мой_бросок = 23 # Error!
-# Arrays
+# Массивы
type
- RollCounter = array[DieFaces, int] # Массивы фиксированной длины и
- DirNames = array[Direction, string] # индексируются любым порядковым типом.
- Truths = array[42..44, bool]
+ СчетчикБросков = array[Кости, int] # Массивы фиксированной длины и
+ ИменаНаправлений = array[Направление, string] # индексируются любым порядковым типом.
+ Истины = array[42..44, bool]
var
- counter: RollCounter
- directions: DirNames
- possible: Truths
+ счетчик: СчетчикБросков
+ направления: ИменаНаправлений
+ возможны: Истины
-possible = [false, false, false] # Массивы создаются литералом [V1,..,Vn]
-possible[42] = true
+возможны = [false, false, false] # Массивы создаются литералом [V1,..,Vn]
+возможны[42] = true
-directions[dNorth] = "Ahh. The Great White North!"
-directions[dWest] = "No, don't go there."
+направления[нСевер] = "ОО. Великий белый Север!"
+направления[нЗапад] = "Нет, не иди туда."
-my_roll = 13
-counter[my_roll] += 1
-counter[my_roll] += 1
+мой_бросок = 13
+счетчик[мой_бросок] += 1
+счетчик[мой_бросок] += 1
-var anotherArray = ["Default index", "starts at", "0"]
+var ещеМассив = ["Идекс по умолчанию", "начинается с", "0"]
# Доступны другие структуры данных, в том числе таблицы, множества,
# списки, очереди и crit-bit деревья.
@@ -169,89 +170,94 @@ var anotherArray = ["Default index", "starts at", "0"]
# `case`, `readLine()`
-echo "Read any good books lately?"
+echo "Читали какие-нибудь хорошие книги в последнее время?"
+
case readLine(stdin)
-of "no", "No":
- echo "Go to your local library."
-of "yes", "Yes":
- echo "Carry on, then."
+of "нет", "Нет":
+ echo "Пойдите в свою местную библиотеку."
+of "да", "Да":
+ echo "Тогда продолжим"
else:
- echo "That's great; I assume."
+ echo "Здорово!"
# `while`, `if`, `continue`, `break`
-import strutils as str # http://nim-lang.org/docs/strutils.html (EN)
-echo "I'm thinking of a number between 41 and 43. Guess which!"
-let number: int = 42
+import strutils as str # http://nim-lang.org/docs/strutils.html (EN)
+echo "Я загадало число между 41 и 43. Отгадай!"
+let число: int = 42
var
- raw_guess: string
- guess: int
-while guess != number:
- raw_guess = readLine(stdin)
- if raw_guess == "": continue # Пропустить эту итерацию
- guess = str.parseInt(raw_guess)
- if guess == 1001:
+ ввод_догадка: string
+ догадка: int
+
+while догадка != число:
+ ввод_догадка = readLine(stdin)
+
+ if ввод_догадка == "": continue # Пропустить эту итерацию
+
+ догадка = str.parseInt(ввод_догадка)
+
+ if догадка == 1001:
echo("AAAAAAGGG!")
break
- elif guess > number:
- echo("Nope. Too high.")
- elif guess < number:
- echo(guess, " is too low")
+ elif догадка > число:
+ echo("Неа. Слишком большое.")
+ elif догадка < число:
+ echo(догадка, " это слишком мало")
else:
- echo("Yeeeeeehaw!")
+ echo("Точнооооо!")
#
# Итерации (циклы)
#
-for i, elem in ["Yes", "No", "Maybe so"]: # Или просто `for elem in`
- echo(elem, " is at index: ", i)
+for i, элем in ["Да", "Нет", "Может быть"]: # Или просто `for элем in`
+ echo(элем, " по индексу: ", i)
-for k, v in items(@[(person: "You", power: 100), (person: "Me", power: 9000)]):
- echo v
+for ключ, значение in items(@[(человек: "You", сила: 100), (человек: "Me", сила: 9000)]):
+ echo значение
-let myString = """
-an <example>
-`string` to
-play with
+let мояСтрока = """
+<пример>
+`строки` для
+тренировки
""" # Многострочная "сырая" строка
-for line in splitLines(myString):
- echo(line)
+for строка in splitLines(мояСтрока):
+ echo(строка)
-for i, c in myString: # Индекс и символ. Или `for j in` только для символов
- if i mod 2 == 0: continue # Компактная форма `if`
- elif c == 'X': break
- else: echo(c)
+for i, симв in мояСтрока: # Индекс и символ. Или `for j in` только для символов
+ if i mod 2 == 0: continue # Компактная форма `if`
+ elif симв == 'X': break
+ else: echo(симв)
#
# Процедуры
#
-type Answer = enum aYes, aNo
+type Ответ = enum оДа, оНет
-proc ask(question: string): Answer =
- echo(question, " (y/n)")
+proc спрос(вопрос: string): Ответ =
+ echo(вопрос, " (д/н)")
while true:
case readLine(stdin)
- of "y", "Y", "yes", "Yes":
- return Answer.aYes # Перечисления могут быть квалифицированы
- of "n", "N", "no", "No":
- return Answer.aNo
- else: echo("Please be clear: yes or no")
-
-proc addSugar(amount: int = 2) = # Значение поумолчанию 2, ничего не возвращает
- assert(amount > 0 and amount < 9000, "Crazy Sugar")
- for a in 1..amount:
- echo(a, " sugar...")
-
-case ask("Would you like sugar in your tea?")
-of aYes:
- addSugar(3)
-of aNo:
- echo "Oh do take a little!"
- addSugar()
-# Здесь нет необходимости в `else`. Возможны только `yes` и `no`.
+ of "д", "Д", "да", "Да":
+ return Ответ.оДа # Перечисления могут быть квалифицированы
+ of "н", "Н", "нет", "Нет":
+ return Ответ.оНет
+ else: echo("Поточнее, да или нет")
+
+proc добавьСахар(количество: int = 2) = # Значение по умолчанию 2, ничего не возвращает
+ assert(количество > 0 and количество < 9000, "Диабет ☠")
+ for a in 1..количество:
+ echo(a, " кубик...")
+
+case спрос("Сахарку?")
+of оДа:
+ добавьСахар(3)
+of оНет:
+ echo "Ну немнооожко!"
+ добавьСахар()
+# Здесь нет необходимости в `else`. Возможны только `да` и `нет`.
#
# FFI (интерфейс внешних функций)
@@ -261,7 +267,7 @@ of aNo:
proc strcmp(a, b: cstring): cint {.importc: "strcmp", nodecl.}
-let cmp = strcmp("C?", "Easy!")
+let cmp = strcmp("C?", "Легко!")
```
Кроме того, Nim выделяется среди себе подобных метапрограммированием,
diff --git a/ru-ru/pascal-ru.html.markdown b/ru-ru/pascal-ru.html.markdown
new file mode 100644
index 00000000..5ea856bc
--- /dev/null
+++ b/ru-ru/pascal-ru.html.markdown
@@ -0,0 +1,217 @@
+---
+language: Pascal
+filename: learnpascal-ru.pas
+contributors:
+ - ["Ganesha Danu", "http://github.com/blinfoldking"]
+ - ["Keith Miyake", "https://github.com/kaymmm"]
+translators:
+ - ["Anton 'Dart' Nikolaev", "https://github.com/dartfnm"]
+lang: ru-ru
+---
+
+
+>Pascal - это процедурный язык программирования, который Никлаус Вирт разработал в 1968–69 годах и опубликовал в 1970 году как небольшой эффективный язык, предназначенный для поощрения хороших методов программирования с использованием структурированного программирования и структурирования данных. Он назван в честь французского математика, философа и физика Блеза Паскаля.
+>
+>source : [wikipedia](https://ru.wikipedia.org/wiki/Паскаль_(язык_программирования)))
+
+
+
+Для компиляции и запуска программы на языке Паскаль вы можете использовать бесплатный компилятор FreePascal. [Скачать здесь](https://www.freepascal.org/)
+
+Либо современный бесплатный компилятор Паскаля нового поколения под платформу .Net [PascalABC.NET](http://pascalabc.net)
+
+```pascal
+// это комментарий
+{
+ а вот это:
+ - комментарий на несколько строк
+}
+
+//объявляем имя программы
+program learn_pascal; //<-- не забываем ставить точку с запятой (;)
+
+const
+ {
+ это секция в которой вы должны объявлять константы
+ }
+type
+ {
+ здесь вы можете объявлять собственные типы данных
+ }
+var
+ {
+ секция для объявления переменных
+ }
+
+begin //начало основной программы
+ {
+ тело вашей программы
+ }
+end. // В конце основной программы обязательно должна стоять точка "."
+```
+
+```pascal
+//объявление переменных
+//вы можете сделать так
+var a:integer;
+var b:integer;
+//или так
+var
+ a : integer;
+ b : integer;
+//или даже так
+var a,b : integer;
+```
+
+```pascal
+program Learn_More;
+
+// Познакомимся с типами данных и с их операциями
+const
+ PI = 3.141592654;
+ GNU = 'GNU''s Not Unix';
+ // имена константам принято давать ЗАГЛАВНЫМИ_БУКВАМИ (в верхнем регистре)
+ // их значения фиксированны т.е никогда не меняются во время выполнения программы
+ // содержат любой стандартный тип данных (integer, real, boolean, char, string)
+
+type
+ ch_array : array [0..255] of char;
+ // массивы - это составной тип данных
+ // мы указываем индекс первого и последнего элемента массива ([0..255])
+ // здесь мы объявили новый тип данных содержащий 255 символов 'char'
+ // (по сути, это просто строка - string[256])
+
+ md_array : array of array of integer;
+ // массив в массиве - по сути является двумерным массивом
+ // можно задать массив нулевой (0) длины, а потом динамически расширить его
+ // это двумерный массив целых чисел
+
+//Объявление переменных
+var
+ int, c, d : integer;
+ // три переменные, которые содержат целые числа
+ // Тип "integer" это 16-битное число в диапазоне [-32,768..32,767]
+ r : real;
+ // переменная типа "real" принимает вещественные (дробные) значения
+ // в диапазоне [3.4E-38..3.4E38]
+ bool : boolean;
+ // переменная логического типа, принимающая булевы-значения: True/False (Правда/Ложь)
+ ch : char;
+ // эта переменная содержит значение кода одного символа
+ // тип 'char' это 8-битное число (1 байт), так что никакого Юникода
+ str : string;
+ // это переменная составного типа, являющееся строкой
+ // по сути, строка это массив в 255 символов длиною, по умолчанию
+
+ s : string[50];
+ // эта строка может содержать максимум 50 символов
+ // вы можете сами указать длину строки, чтобы минимизировать использование памяти
+ my_str: ch_array;
+ // вы можете объявлять переменные собственных типов
+ my_2d : md_array;
+ // динамически расширяемые массивы требуют указания длины перед их использованием.
+
+ // дополнительные целочисленные типы данных
+ b : byte; // диапазон [0..255]
+ shi : shortint; // диапазон [-128..127]
+ smi : smallint; // диапазон [-32,768..32,767] (стандартный Integer)
+ w : word; // диапазон [0..65,535]
+ li : longint; // диапазон [-2,147,483,648..2,147,483,647]
+ lw : longword; // диапазон [0..4,294,967,295]
+ c : cardinal; // тоже что и longword
+ i64 : int64; // диапазон [-9223372036854775808..9223372036854775807]
+ qw : qword; // диапазон [0..18,446,744,073,709,551,615]
+
+ // дополнительные вещественные типы данных (дробные)
+ rr : real; // диапазон зависит от платформы (т.е. 8-бит, 16-бит и т.д.)
+ rs : single; // диапазон [1.5E-45..3.4E38]
+ rd : double; // диапазон [5.0E-324 .. 1.7E308]
+ re : extended; // диапазон [1.9E-4932..1.1E4932]
+ rc : comp; // диапазон [-2E64+1 .. 2E63-1]
+
+Begin
+ int := 1; // так мы присваиваем значение переменной
+ r := 3.14;
+ ch := 'a';
+ str := 'apple';
+ bool := true;
+ // Паскаль не чувствителен к регистру
+
+ // арифметические операции
+ int := 1 + 1; // int = 2; заменяет предыдущее значение
+ int := int + 1; // int = 2 + 1 = 3;
+ int := 4 div 2; //int = 2; 'div' операция деления, с отбрасыванием дробной части
+ int := 3 div 2; //int = 1;
+ int := 1 div 2; //int = 0;
+
+ bool := true or false; // bool = true
+ bool := false and true; // bool = false
+ bool := true xor true; // bool = false
+
+ r := 3 / 2; // деления вещественных чисел с дробной частью
+ r := int; // вещественной переменной можно присвоить целочисленное значение, но не наоборот
+
+ my_str[0] := 'a'; // для доступа к элементу массива нужно указать его индекс в квадратных скобках ([0])
+
+ c := str[1]; // первая буква во всех Строках находится по индексу [1]
+ str := 'hello' + 'world'; //объединяем 2 строки в одну
+
+ SetLength(my_2d,10,10); // инициализируем динамически расширяемый массив
+ // задаём размер 2х-мерного массива 10×10
+
+ // первый элемент массива лежит в индексе [0], последний [длина_массива-1]
+ for c := 0 to 9 do
+ for d := 0 to 9 do // переменные для счетчиков циклов должны быть объявлены
+ my_2d[c,d] := c * d;
+ // обращаться к многомерным массивам нужно с помощью одного набора скобок
+
+End.
+```
+
+```pascal
+program Functional_Programming;
+
+Var
+ i, dummy : integer;
+
+function factorial_recursion(const a: integer) : integer;
+{ Функция расчёта Факториала целочисленного параметра 'a', рекурсивно. Возвращает целое значение }
+
+// Мы можем объявлять локальные переменные внутри своей функции:
+// Var
+// local_a : integer;
+
+Begin
+ If a >= 1 Then
+ factorial_recursion := a * factorial_recursion(a-1)
+ // возвращаем результат, присваивая найденное значение переменной с тем же именем, как у функции
+ Else
+ factorial_recursion := 1;
+End; // Для завершения функции, используется символ ";" после оператора "End;"
+
+
+
+procedure get_integer( var i : integer; dummy : integer );
+{ Эта процедура ждёт от пользователя ввода целого числа и возвращает его значение через параметр i.
+ Если параметр функции начинается с 'var', это означает, что его значение было передано, по ссылке, то есть, оно может использоваться не только как входное значение, но и для возвращения дополнительных результатов работы функции.
+ Параметры функции (без 'var'), (такие как "dummy" (пустышка)), передаются по значению, и по сути являются - локальными переменными, таким образом изменения, внесенные внутри функции/процедуры, не влияют на значение переменной за её пределами.
+}
+Begin // начало процедуры
+ write('Введите целое число: ');
+ readln(i); // число, введённое пользователем, сохранится в переменной i
+ // и её значение будет доступно вызывающей подпрограмме
+
+ dummy := 4; // значение 'dummy' не будет влиять на значения переменной вне процедуры
+End; // конец процедуры
+
+Begin // главный блок программы
+ dummy := 3;
+ get_integer(i, dummy); // вызываем процедуру получения числа от пользователя
+ writeln(i, '! = ', factorial_recursion(i)); // ввыводим значение факториала от i
+
+ writeln('dummy = ', dummy);
+ // всегда выводит "3", поскольку фиктивная переменная не изменяется.
+End. // конец программы
+
+```
+
diff --git a/ru-ru/perl-ru.html.markdown b/ru-ru/perl-ru.html.markdown
index a907ba41..a9bb683b 100644
--- a/ru-ru/perl-ru.html.markdown
+++ b/ru-ru/perl-ru.html.markdown
@@ -9,12 +9,12 @@ translators:
lang: ru-ru
---
-Perl 5 -- высокоуровневый мощный язык с 25-летней историей.
-Особенно хорош для обработки разнообразных текстовых данных.
+Perl -- высокоуровневый мощный язык с 25-летней историей.
+Особенно хорош для обработки разнообразных текстовых данных.
-Perl 5 работает более чем на 100 платформах, от портативных устройств
-до мейнфреймов, и подходит как для быстрого прототипирования,
-так и для крупных проектов.
+Perl работает более чем на 100 платформах, от портативных устройств
+до мейнфреймов, и подходит как для быстрого прототипирования,
+так и для крупных проектов.
```perl
# Комментарии начинаются с символа решетки.
@@ -23,8 +23,8 @@ Perl 5 работает более чем на 100 платформах, от п
#### Типы переменных в Perl
# Скалярные переменные начинаются с знака доллара $.
-# Имя переменной состоит из букв, цифр и знаков подчеркивания,
-# начиная с буквы или подчеркивания.
+# Имя переменной состоит из букв, цифр и знаков подчеркивания,
+# начиная с буквы или подчеркивания.
### В Perl три основных типа переменных: скаляры, массивы, хеши.
@@ -55,7 +55,7 @@ my %fruit_color = (
banana => "yellow",
);
-# Важно: вставка и поиск в хеше выполняются за константное время,
+# Важно: вставка и поиск в хеше выполняются за константное время,
# независимо от его размера.
# Скаляры, массивы и хеши подробно описаны в разделе perldata
@@ -81,7 +81,7 @@ unless ( condition ) {
}
# Это более читаемый вариант для "if (!condition)"
-# Специфические Perl-овые пост-условия:
+# Специфические Perl-овые пост-условия:
print "Yow!" if $zippy;
print "We have no bananas" unless $bananas;
@@ -129,7 +129,7 @@ open(my $out, ">", "output.txt") or die "Can't open output.txt: $!";
open(my $log, ">>", "my.log") or die "Can't open my.log: $!";
# Читать из файлового дескриптора можно с помощью оператора "<>".
-# В скалярном контексте он читает одну строку из файла, в списковом --
+# В скалярном контексте он читает одну строку из файла, в списковом --
# читает сразу весь файл, сохраняя по одной строке в элементе массива:
my $line = <$in>;
@@ -152,13 +152,13 @@ logger("We have a logger subroutine!");
#### Perl-модули
-Perl-овые модули предоставляют широкий набор функциональности,
-так что вы можете не изобретать заново велосипеды, а просто скачать
-нужный модуль с CPAN (http://www.cpan.org/).
-Некоторое количество самых полезных модулей включено в стандартную
+Perl-овые модули предоставляют широкий набор функциональности,
+так что вы можете не изобретать заново велосипеды, а просто скачать
+нужный модуль с CPAN (http://www.cpan.org/).
+Некоторое количество самых полезных модулей включено в стандартную
поставку Perl.
-Раздел документации perlfaq содержит вопросы и ответы о многих частых
+Раздел документации perlfaq содержит вопросы и ответы о многих частых
задачах, и часто предлагает подходящие CPAN-модули.
diff --git a/ru-ru/python-ru.html.markdown b/ru-ru/python-ru.html.markdown
index b2c00baf..e0e53b9c 100644
--- a/ru-ru/python-ru.html.markdown
+++ b/ru-ru/python-ru.html.markdown
@@ -6,6 +6,7 @@ contributors:
- ["Steven Basart", "http://github.com/xksteven"]
translators:
- ["Andre Polykanine", "https://github.com/Oire"]
+ - ["Anton Grouchtchak", "https://github.com/Teraskull"]
filename: learnpython-ru.py
---
@@ -20,8 +21,10 @@ filename: learnpython-ru.py
Если вы хотите изучить Python 2.7, обратитесь к другой статье.
```python
+
# Однострочные комментарии начинаются с символа решётки.
-""" Многострочный текст может быть
+
+""" Многострочный текст может быть
записан, используя 3 знака " и обычно используется
в качестве встроенной документации
"""
@@ -31,315 +34,397 @@ filename: learnpython-ru.py
####################################################
# У вас есть числа
-3 #=> 3
+3 # => 3
# Математика работает вполне ожидаемо
-1 + 1 #=> 2
-8 - 1 #=> 7
-10 * 2 #=> 20
-
-# Кроме деления, которое по умолчанию возвращает число с плавающей запятой
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
35 / 5 # => 7.0
# Результат целочисленного деления округляется в меньшую сторону
# как для положительных, так и для отрицательных чисел.
-5 // 3 # => 1
-5.0 // 3.0 # => 1.0 # работает и для чисел с плавающей запятой
--5 // 3 # => -2
+5 // 3 # => 1
+-5 // 3 # => -2
+5.0 // 3.0 # => 1.0 # работает и для чисел с плавающей запятой
-5.0 // 3.0 # => -2.0
-# Когда вы используете числа с плавающей запятой,
-# результатом будет также число с плавающей запятой
-3 * 2.0 # => 6.0
+# # Результат деления возвращает число с плавающей запятой
+10.0 / 3 # => 3.3333333333333335
# Остаток от деления
-7 % 3 # => 1
+7 % 3 # => 1
# Возведение в степень
-2**4 # => 16
+2**3 # => 8
# Приоритет операций указывается скобками
-(1 + 3) * 2 #=> 8
+1 + 3 * 2 # => 7
+(1 + 3) * 2 # => 8
-# Для логических (булевых) значений существует отдельный примитивный тип
-True
-False
+# Булевы значения - примитивы (Обратите внимание на заглавную букву)
+True # => True
+False # => False
# Для отрицания используется ключевое слово not
-not True #=> False
-not False #=> True
-
-# Логические операторы
-# Обратите внимание: ключевые слова «and» и «or» чувствительны к регистру букв
-True and False #=> False
-False or True #=> True
-
-# Обратите внимание, что логические операторы используются и с целыми числами
-0 and 2 #=> 0
--5 or 0 #=> -5
-0 == False #=> True
-2 == True #=> False
-1 == True #=> True
+not True # => False
+not False # => True
+
+# Булевы операторы
+# Обратите внимание: ключевые слова "and" и "or" чувствительны к регистру букв
+True and False # => False
+False or True # => True
+
+# True и False на самом деле 1 и 0, но с разными ключевыми словами
+True + True # => 2
+True * 8 # => 8
+False - 5 # => -5
+
+# Операторы сравнения обращают внимание на числовое значение True и False
+0 == False # => True
+1 == True # => True
+2 == True # => False
+-5 != False # => True
+
+# Использование булевых логических операторов на типах int превращает их в булевы значения, но возвращаются оригинальные значения
+# Не путайте с bool(ints) и bitwise and/or (&,|)
+bool(0) # => False
+bool(4) # => True
+bool(-6) # => True
+0 and 2 # => 0
+-5 or 0 # => -5
# Равенство — это ==
-1 == 1 #=> True
-2 == 1 #=> False
+1 == 1 # => True
+2 == 1 # => False
# Неравенство — это !=
-1 != 1 #=> False
-2 != 1 #=> True
+1 != 1 # => False
+2 != 1 # => True
# Ещё немного сравнений
-1 < 10 #=> True
-1 > 10 #=> False
-2 <= 2 #=> True
-2 >= 2 #=> True
-
-# Сравнения могут быть записаны цепочкой:
-1 < 2 < 3 #=> True
-2 < 3 < 2 #=> False
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# Проверка, находится ли значение в диапазоне
+1 < 2 and 2 < 3 # => True
+2 < 3 and 3 < 2 # => False
+
+# Сравнения могут быть записаны цепочкой
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# (is vs. ==) ключевое слово is проверяет, относятся ли две переменные к одному и тому же объекту, но == проверяет если указанные объекты имеют одинаковые значения.
+a = [1, 2, 3, 4] # a указывает на новый список, [1, 2, 3, 4]
+b = a # b указывает на то, что указывает a
+b is a # => True, a и b относятся к одному и тому же объекту
+b == a # => True, Объекты a и b равны
+b = [1, 2, 3, 4] # b указывает на новый список, [1, 2, 3, 4]
+b is a # => False, a и b не относятся к одному и тому же объекту
+b == a # => True, Объекты a и b равны
# Строки определяются символом " или '
"Это строка."
'Это тоже строка.'
# И строки тоже могут складываться! Хотя лучше не злоупотребляйте этим.
-"Привет " + "мир!" #=> "Привет мир!"
+"Привет " + "мир!" # => "Привет мир!"
-# Строки можно умножать.
-"aa" * 4 #=> "aaaaaaaa"
+# Строки (но не переменные) могут быть объединены без использования '+'
+"Привет " "мир!" # => "Привет мир!"
# Со строкой можно работать, как со списком символов
-"Это строка"[0] #=> 'Э'
+"Привет мир!"[0] # => 'П'
-# Метод format используется для форматирования строк:
-"{0} могут быть {1}".format("строки", "форматированы")
+# Вы можете найти длину строки
+len("Это строка") # => 10
-# Вы можете повторять аргументы форматирования, чтобы меньше печатать.
-"Ехал {0} через реку, видит {0} - в реке {1}! Сунул {0} руку в реку, {1} за руку греку цап!".format("грека", "рак")
-#=> "Ехал грека через реку, видит грека - в реке рак! Сунул грека руку в реку, рак за руку греку цап!"
-# Если вы не хотите считать, можете использовать ключевые слова.
-"{name} хочет есть {food}".format(name="Боб", food="лазанью")
+# Вы также можете форматировать, используя f-строки (в Python 3.6+)
+name = "Рейко"
+f"Она сказала, что ее зовут {name}." # => "Она сказала, что ее зовут Рейко"
+# Вы можете поместить любой оператор Python в фигурные скобки, и он будет выведен в строке.
+f"{name} состоит из {len(name)} символов." # => "Рэйко состоит из 5 символов."
-# Если ваш код на Python 3 нужно запускать также и под Python 2.5 и ниже,
-# вы также можете использовать старый способ форматирования:
-"%s можно %s %s способом" % ("строки", "интерполировать", "старым")
# None является объектом
-None #=> None
+None # => None
-# Не используйте оператор равенства '==' для сравнения
-# объектов с None. Используйте для этого 'is'
-"etc" is None #=> False
-None is None #=> True
+# Не используйте оператор равенства "==" для сравнения
+# объектов с None. Используйте для этого "is"
+"etc" is None # => False
+None is None # => True
-# Оператор «is» проверяет идентичность объектов. Он не
-# очень полезен при работе с примитивными типами, но
-# зато просто незаменим при работе с объектами.
-
-# None, 0 и пустые строки/списки/словари приводятся к False.
+# None, 0 и пустые строки/списки/словари/кортежи приводятся к False.
# Все остальные значения равны True
-bool(0) # => False
+bool(0) # => False
bool("") # => False
-bool([]) #=> False
-bool({}) #=> False
+bool([]) # => False
+bool({}) # => False
+bool(()) # => False
####################################################
-## 2. Переменные и коллекции
+## 2. Переменные и Коллекции
####################################################
# В Python есть функция Print
-print("Я Python. Приятно познакомиться!")
+print("Я Python. Приятно познакомиться!") # => Я Python. Приятно познакомиться!
+
+# По умолчанию функция, print() также выводит новую строку в конце.
+# Используйте необязательный аргумент end, чтобы изменить последнюю строку.
+print("Привет мир", end="!") # => Привет мир!
+
+# Простой способ получить входные данные из консоли
+input_string_var = input("Введите данные: ") # Возвращает данные в виде строки
+# Примечание: в более ранних версиях Python метод input() назывался raw_input()
# Объявлять переменные перед инициализацией не нужно.
# По соглашению используется нижний_регистр_с_подчёркиваниями
some_var = 5
-some_var #=> 5
+some_var # => 5
+
+# При попытке доступа к неинициализированной переменной выбрасывается исключение.
+# Об исключениях см. раздел "Поток управления и итерируемые объекты".
+some_unknown_var # Выбрасывает ошибку NameError
-# При попытке доступа к неинициализированной переменной
-# выбрасывается исключение.
-# Об исключениях см. раздел «Поток управления и итерируемые объекты».
-some_unknown_var # Выбрасывает ошибку именования
+# if можно использовать как выражение
+# Эквивалент тернарного оператора '?:' в C
+"да!" if 0 > 1 else "нет!" # => "нет!"
# Списки хранят последовательности
li = []
# Можно сразу начать с заполненного списка
other_li = [4, 5, 6]
-# Объекты добавляются в конец списка методом append
-li.append(1) # [1]
-li.append(2) # [1, 2]
-li.append(4) # [1, 2, 4]
-li.append(3) # [1, 2, 4, 3]
-# И удаляются с конца методом pop
-li.pop() #=> возвращает 3 и li становится равен [1, 2, 4]
+# Объекты добавляются в конец списка методом append()
+li.append(1) # [1]
+li.append(2) # [1, 2]
+li.append(4) # [1, 2, 4]
+li.append(3) # [1, 2, 4, 3]
+# И удаляются с конца методом pop()
+li.pop() # => возвращает 3 и li становится равен [1, 2, 4]
# Положим элемент обратно
-li.append(3) # [1, 2, 4, 3].
+li.append(3) # [1, 2, 4, 3].
# Обращайтесь со списком, как с обычным массивом
-li[0] #=> 1
+li[0] # => 1
+
# Обратимся к последнему элементу
-li[-1] #=> 3
+li[-1] # => 3
# Попытка выйти за границы массива приведёт к ошибке индекса
-li[4] # Выдаёт IndexError
+li[4] # Выбрасывает ошибку IndexError
# Можно обращаться к диапазону, используя так называемые срезы
# (Для тех, кто любит математику, это называется замкнуто-открытый интервал).
-li[1:3] #=> [2, 4]
-# Опускаем начало
-li[2:] #=> [4, 3]
-# Опускаем конец
-li[:3] #=> [1, 2, 4]
-# Выбираем каждый второй элемент
-li[::2] # =>[1, 4]
-# Переворачиваем список
-li[::-1] # => [3, 4, 2, 1]
+li[1:3] # Вернуть список из индекса с 1 по 3 => [2, 4]
+li[2:] # Вернуть список, начиная с индекса 2 => [4, 3]
+li[:3] # Вернуть список с начала до индекса 3 => [1, 2, 4]
+li[::2] # Вернуть список, выбирая каждую вторую запись => [1, 4]
+li[::-1] # Вернуть список в обратном порядке => [3, 4, 2, 1]
# Используйте сочетания всего вышеназванного для выделения более сложных срезов
# li[начало:конец:шаг]
+# Сделать однослойную глубокую копию, используя срезы
+li2 = li[:] # => li2 = [1, 2, 4, 3], но (li2 is li) вернет False.
+
# Удаляем произвольные элементы из списка оператором del
-del li[2] # [1, 2, 3]
+del li[2] # [1, 2, 3]
+
+# Удалить первое вхождение значения
+li.remove(2) # [1, 3]
+li.remove(2) # Выбрасывает ошибку ValueError поскольку 2 нет в списке
+
+# Вставить элемент по определенному индексу
+li.insert(1, 2) # [1, 2, 3]
+
+# Получить индекс первого найденного элемента, соответствующего аргументу
+li.index(2) # => 1
+li.index(4) # Выбрасывает ошибку ValueError поскольку 4 нет в списке
# Вы можете складывать, или, как ещё говорят, конкатенировать списки
# Обратите внимание: значения li и other_li при этом не изменились.
-li + other_li #=> [1, 2, 3, 4, 5, 6] — Замечание: li и other_li не изменяются
+li + other_li # => [1, 2, 3, 4, 5, 6]
-# Объединять списки можно методом extend
+# Объединять списки можно методом extend()
li.extend(other_li) # Теперь li содержит [1, 2, 3, 4, 5, 6]
-# Проверить элемент на вхождение в список можно оператором in
-1 in li #=> True
+# Проверить элемент на наличие в списке можно оператором in
+1 in li # => True
# Длина списка вычисляется функцией len
-len(li) #=> 6
+len(li) # => 6
-# Кортежи — это такие списки, только неизменяемые
+# Кортежи похожи на списки, только неизменяемые
tup = (1, 2, 3)
-tup[0] #=> 1
-tup[0] = 3 # Выдаёт TypeError
+tup[0] # => 1
+tup[0] = 3 # Выбрасывает ошибку TypeError
+
+# Обратите внимание, что кортеж длины 1 должен иметь запятую после последнего элемента, но кортежи другой длины, даже 0, не должны.
+type((1)) # => <class 'int'>
+type((1,)) # => <class 'tuple'>
+type(()) # => <class 'tuple'>
# Всё то же самое можно делать и с кортежами
-len(tup) #=> 3
-tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
-tup[:2] #=> (1, 2)
-2 in tup #=> True
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
# Вы можете распаковывать кортежи (или списки) в переменные
-a, b, c = (1, 2, 3) # a == 1, b == 2 и c == 3
+a, b, c = (1, 2, 3) # a == 1, b == 2 и c == 3
+# Вы также можете сделать расширенную распаковку
+a, *b, c = (1, 2, 3, 4) # a теперь 1, b теперь [2, 3] и c теперь 4
# Кортежи создаются по умолчанию, если опущены скобки
-d, e, f = 4, 5, 6
+d, e, f = 4, 5, 6 # кортеж 4, 5, 6 распаковывается в переменные d, e и f
+# соответственно, d = 4, e = 5 и f = 6
# Обратите внимание, как легко поменять местами значения двух переменных
-e, d = d, e # теперь d == 5, а e == 4
+e, d = d, e # теперь d == 5, а e == 4
-# Словари содержат ассоциативные массивы
+# Словари содержат ассоциативные массивы
empty_dict = {}
# Вот так описывается предзаполненный словарь
filled_dict = {"one": 1, "two": 2, "three": 3}
-# Значения извлекаются так же, как из списка, с той лишь разницей,
-# что индекс — у словарей он называется ключом — не обязан быть числом
-filled_dict["one"] #=> 1
+# Обратите внимание, что ключи для словарей должны быть неизменяемыми типами. Это
+# сделано для того, чтобы ключ может быть преобразован в хеш для быстрого поиска.
+# Неизменяемые типы включают целые числа, числа с плавающей запятой, строки, кортежи.
+invalid_dict = {[1,2,3]: "123"} # => Выбрасывает ошибку TypeError: unhashable type: 'list'
+valid_dict = {(1,2,3):[1,2,3]} # Однако значения могут быть любого типа.
-# Все ключи в виде списка получаются с помощью метода keys().
+# Поиск значений с помощью []
+filled_dict["one"] # => 1
+
+# Все ключи в виде списка получаются с помощью метода keys().
# Его вызов нужно обернуть в list(), так как обратно мы получаем
-# итерируемый объект, о которых поговорим позднее.
-list(filled_dict.keys()) # => ["three", "two", "one"]
-# Замечание: сохранение порядка ключей в словаре не гарантируется
-# Ваши результаты могут не совпадать с этими.
+# итерируемый объект, о которых поговорим позднее. Примечание - для Python
+# версии <3.7, порядок словарных ключей не гарантируется. Ваши результаты могут
+# не точно соответствовать приведенному ниже примеру. Однако, начиная с Python 3.7
+# элементы в словаре сохраняют порядок, в котором они вставляются в словарь.
+list(filled_dict.keys()) # => ["three", "two", "one"] в Python <3.7
+list(filled_dict.keys()) # => ["one", "two", "three"] в Python 3.7+
+
# Все значения в виде списка можно получить с помощью values().
# И снова нам нужно обернуть вызов в list(), чтобы превратить
# итерируемый объект в список.
-list(filled_dict.values()) # => [3, 2, 1]
# То же самое замечание насчёт порядка ключей справедливо и здесь
+list(filled_dict.values()) # => [3, 2, 1] в Python <3.7
+list(filled_dict.values()) # => [1, 2, 3] в Python 3.7+
-# При помощи оператора in можно проверять ключи на вхождение в словарь
-"one" in filled_dict #=> True
-1 in filled_dict #=> False
+# При помощи ключевого слова in можно проверять наличие ключей в словаре
+"one" in filled_dict # => True
+1 in filled_dict # => False
-# Попытка получить значение по несуществующему ключу выбросит ошибку ключа
-filled_dict["four"] # KeyError
+# Попытка получить значение по несуществующему ключу выбросит ошибку KeyError
+filled_dict["four"] # Выбрасывает ошибку KeyError
# Чтобы избежать этого, используйте метод get()
-filled_dict.get("one") #=> 1
-filled_dict.get("four") #=> None
-# Метод get также принимает аргумент по умолчанию, значение которого будет
-# возвращено при отсутствии указанного ключа
-filled_dict.get("one", 4) #=> 1
-filled_dict.get("four", 4) #=> 4
+filled_dict.get("one") # => 1
+filled_dict.get("four") # => None
+# Метод get поддерживает аргумент по умолчанию, когда значение отсутствует
+filled_dict.get("one", 4) # => 1
+filled_dict.get("four", 4) # => 4
-# Метод setdefault вставляет пару ключ-значение, только если такого ключа нет
-filled_dict.setdefault("five", 5) #filled_dict["five"] возвращает 5
-filled_dict.setdefault("five", 6) #filled_dict["five"] по-прежнему возвращает 5
+# Метод setdefault() вставляет пару ключ-значение, только если такого ключа нет
+filled_dict.setdefault("five", 5) # filled_dict["five"] возвращает 5
+filled_dict.setdefault("five", 6) # filled_dict["five"] по-прежнему возвращает 5
# Добавление элементов в словарь
-filled_dict.update({"four":4}) #=> {"one": 1, "two": 2, "three": 3, "four": 4}
-#filled_dict["four"] = 4 # Другой способ добавления элементов
+filled_dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4}
+filled_dict["four"] = 4 # Другой способ добавления элементов
+
+# Удаляйте ключи из словаря с помощью ключевого слова del
+del filled_dict["one"] # Удаляет ключ "one" из словаря
+
+# После Python 3.5 вы также можете использовать дополнительные параметры распаковки
+{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2}
+{'a': 1, **{'a': 2}} # => {'a': 2}
-# Удаляйте ключи из словаря с помощью оператора del
-del filled_dict["one"] # Удаляет ключ «one» из словаря
# Множества содержат... ну, в общем, множества
empty_set = set()
# Инициализация множества набором значений.
-# Да, оно выглядит примерно как словарь… ну извините, так уж вышло.
-filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
+# Да, оно выглядит примерно как словарь. Ну извините, так уж вышло.
+filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
+
+# Similar to keys of a dictionary, elements of a set have to be immutable.
+# Как и ключи словаря, элементы множества должны быть неизменяемыми.
+invalid_set = {[1], 1} # => Выбрасывает ошибку TypeError: unhashable type: 'list'
+valid_set = {(1,), 1}
# Множеству можно назначать новую переменную
filled_set = some_set
-
-# Добавление новых элементов в множество
-filled_set.add(5) # filled_set равно {1, 2, 3, 4, 5}
+filled_set.add(5) # {1, 2, 3, 4, 5}
+# В множествах нет повторяющихся элементов
+filled_set.add(5) # {1, 2, 3, 4, 5}
# Пересечение множеств: &
other_set = {3, 4, 5, 6}
-filled_set & other_set #=> {3, 4, 5}
+filled_set & other_set # => {3, 4, 5}
# Объединение множеств: |
-filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+filled_set | other_set # => {1, 2, 3, 4, 5, 6}
# Разность множеств: -
-{1,2,3,4} - {2,3,5} #=> {1, 4}
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
+
+# Симметричная разница: ^
+{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5}
+
+# Проверить, является ли множество слева надмножеством множества справа
+{1, 2} >= {1, 2, 3} # => False
-# Проверка на вхождение во множество: in
-2 in filled_set #=> True
-10 in filled_set #=> False
+# Проверить, является ли множество слева подмножеством множества справа
+{1, 2} <= {1, 2, 3} # => True
+
+# Проверка на наличие в множестве: in
+2 in filled_set # => True
+10 in filled_set # => False
+
+# Сделать однослойную глубокую копию
+filled_set = some_set.copy() # {1, 2, 3, 4, 5}
+filled_set is some_set # => False
####################################################
## 3. Поток управления и итерируемые объекты
####################################################
-# Для начала заведём переменную
+# Для начала создадим переменную
some_var = 5
# Так выглядит выражение if. Отступы в python очень важны!
-# результат: «some_var меньше, чем 10»
+# Конвенция заключается в использовании четырех пробелов, а не табуляции.
+# Pезультат: "some_var меньше, чем 10"
if some_var > 10:
- print("some_var намного больше, чем 10.")
-elif some_var < 10: # Выражение elif необязательно.
+ print("some_var точно больше, чем 10.")
+elif some_var < 10: # Выражение elif необязательно.
print("some_var меньше, чем 10.")
-else: # Это тоже необязательно.
+else: # Это тоже необязательно.
print("some_var равно 10.")
-# Циклы For проходят по спискам. Результат:
- # собака — это млекопитающее
- # кошка — это млекопитающее
- # мышь — это млекопитающее
+"""
+Циклы For проходят по спискам.
+Выводит:
+ собака — это млекопитающее
+ кошка — это млекопитающее
+ мышь — это млекопитающее
+"""
for animal in ["собака", "кошка", "мышь"]:
# Можете использовать format() для интерполяции форматированных строк
print("{} — это млекопитающее".format(animal))
-
+
"""
-«range(число)» возвращает список чисел
+"range(число)" возвращает список чисел
от нуля до заданного числа
-Результат:
+Выводит:
0
1
2
@@ -349,8 +434,42 @@ for i in range(4):
print(i)
"""
+"range(нижнее, верхнее)" возвращает список чисел
+от нижнего числа к верхнему
+Выводит:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print(i)
+
+"""
+"range(нижнее, верхнее, шаг)" возвращает список чисел
+от нижнего числа к верхнему, от нижнего числа к верхнему, увеличивая
+шаг за шагом. Если шаг не указан, значение по умолчанию - 1.
+Выводит:
+ 4
+ 6
+"""
+for i in range(4, 8, 2):
+ print(i)
+
+"""
+Чтобы перебрать список и получить индекс и значение каждого элемента в списке
+Выводит:
+ 0 собака
+ 1 кошка
+ 2 мышь
+"""
+animals = ["собака", "кошка", "мышь"]
+for i, value in enumerate(animals):
+ print(i, value)
+
+"""
Циклы while продолжаются до тех пор, пока указанное условие не станет ложным.
-Результат:
+Выводит:
0
1
2
@@ -366,45 +485,77 @@ try:
# Чтобы выбросить ошибку, используется raise
raise IndexError("Это ошибка индекса")
except IndexError as e:
- # pass — это просто отсутствие оператора. Обычно здесь происходит
- # восстановление после ошибки.
- pass
+ pass # pass — это просто отсутствие оператора. Обычно здесь происходит восстановление после ошибки.
except (TypeError, NameError):
- pass # Несколько исключений можно обработать вместе, если нужно.
-else: # Необязательное выражение. Должно следовать за последним блоком except
- print("Всё хорошо!") # Выполнится, только если не было никаких исключений
+ pass # Несколько исключений можно обработать вместе, если нужно.
+else: # Необязательное выражение. Должно следовать за последним блоком except
+ print("Всё хорошо!") # Выполнится, только если не было никаких исключений
+finally: # Выполнить при любых обстоятельствах
+ print("Мы можем очистить ресурсы здесь")
+
+# Вместо try/finally чтобы очистить ресурсы, можно использовать оператор with
+with open("myfile.txt") as f:
+ for line in f:
+ print(line)
+
+# Запись в файл
+contents = {"aa": 12, "bb": 21}
+with open("myfile1.txt", "w+") as file:
+ file.write(str(contents)) # Записывает строку в файл
+
+with open("myfile2.txt", "w+") as file:
+ file.write(json.dumps(contents)) # Записывает объект в файл
+
+# Чтение из файла
+with open('myfile1.txt', "r+") as file:
+ contents = file.read() # Читает строку из файла
+print(contents)
+# print: {"aa": 12, "bb": 21}
+
+with open('myfile2.txt', "r+") as file:
+ contents = json.load(file) # Читает объект json из файла
+print(contents)
+# print: {"aa": 12, "bb": 21}
+
# Python предоставляет фундаментальную абстракцию,
-# которая называется итерируемым объектом (an iterable).
+# которая называется итерируемым объектом (Iterable).
# Итерируемый объект — это объект, который воспринимается как последовательность.
# Объект, который возвратила функция range(), итерируемый.
+
filled_dict = {"one": 1, "two": 2, "three": 3}
our_iterable = filled_dict.keys()
-print(our_iterable) #=> range(1,10). Это объект, реализующий интерфейс iterable
+print(our_iterable) # => dict_keys(['one', 'two', 'three']). Это объект, реализующий интерфейс Iterable
# Мы можем проходить по нему циклом.
for i in our_iterable:
- print(i) # Выводит one, two, three
+ print(i) # Выводит one, two, three
# Но мы не можем обращаться к элементу по индексу.
-our_iterable[1] # Выбрасывает ошибку типа
+our_iterable[1] # Выбрасывает ошибку TypeError
# Итерируемый объект знает, как создавать итератор.
our_iterator = iter(our_iterable)
# Итератор может запоминать состояние при проходе по объекту.
-# Мы получаем следующий объект, вызывая функцию __next__.
-our_iterator.__next__() #=> "one"
+# Мы получаем следующий объект, вызывая функцию next().
+next(our_iterator) # => "one"
-# Он сохраняет состояние при вызове __next__.
-our_iterator.__next__() #=> "two"
-our_iterator.__next__() #=> "three"
+# Он сохраняет состояние при вызове next().
+next(our_iterator) # => "two"
+next(our_iterator) # => "three"
# Возвратив все данные, итератор выбрасывает исключение StopIterator
-our_iterator.__next__() # Выбрасывает исключение остановки итератора
+next(our_iterator) # Выбрасывает исключение StopIteration
+
+# Мы можем проходить по нему циклом.
+our_iterator = iter(our_iterable)
+for i in our_iterator:
+ print(i) # Выводит one, two, three
# Вы можете получить сразу все элементы итератора, вызвав на нём функцию list().
-list(filled_dict.keys()) #=> Возвращает ["one", "two", "three"]
+list(our_iterable) # => Возвращает ["one", "two", "three"]
+list(our_iterator) # => Возвращает [] потому что состояние сохраняется
####################################################
@@ -414,19 +565,19 @@ list(filled_dict.keys()) #=> Возвращает ["one", "two", "three"]
# Используйте def для создания новых функций
def add(x, y):
print("x равен %s, а y равен %s" % (x, y))
- return x + y # Возвращайте результат с помощью ключевого слова return
+ return x + y # Возвращайте результат с помощью ключевого слова return
# Вызов функции с аргументами
-add(5, 6) #=> выводит «x равен 5, а y равен 6» и возвращает 11
+add(5, 6) # => Выводит "x равен 5, а y равен 6" и возвращает 11
# Другой способ вызова функции — вызов с именованными аргументами
-add(y=6, x=5) # Именованные аргументы можно указывать в любом порядке.
+add(y=6, x=5) # Именованные аргументы можно указывать в любом порядке.
# Вы можете определить функцию, принимающую переменное число аргументов
def varargs(*args):
return args
-varargs(1, 2, 3) #=> (1,2,3)
+varargs(1, 2, 3) # => (1,2,3)
# А также можете определить функцию, принимающую переменное число
@@ -435,7 +586,7 @@ def keyword_args(**kwargs):
return kwargs
# Вызовем эту функцию и посмотрим, что из этого получится
-keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
# Если хотите, можете использовать оба способа одновременно
def all_the_args(*args, **kwargs):
@@ -451,70 +602,135 @@ all_the_args(1, 2, a=3, b=4) выводит:
# Используйте символ * для распаковки кортежей и ** для распаковки словарей
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
-all_the_args(*args) # эквивалентно foo(1, 2, 3, 4)
-all_the_args(**kwargs) # эквивалентно foo(a=3, b=4)
-all_the_args(*args, **kwargs) # эквивалентно foo(1, 2, 3, 4, a=3, b=4)
+all_the_args(*args) # эквивалентно all_the_args(1, 2, 3, 4)
+all_the_args(**kwargs) # эквивалентно all_the_args(a=3, b=4)
+all_the_args(*args, **kwargs) # эквивалентно all_the_args(1, 2, 3, 4, a=3, b=4)
+
+# Возврат нескольких значений (с назначением кортежей)
+def swap(x, y):
+ return y, x # Возвращает несколько значений в виде кортежа без скобок.
+ # (Примечание: скобки исключены, но могут быть включены)
+
+x = 1
+y = 2
+x, y = swap(x, y) # => x = 2, y = 1
+# (x, y) = swap(x,y) # Снова, скобки были исключены, но могут быть включены.
# Область определения функций
x = 5
-def setX(num):
+def set_x(num):
# Локальная переменная x — это не то же самое, что глобальная переменная x
- x = num # => 43
- print (x) # => 43
-
-def setGlobalX(num):
+ x = num # => 43
+ print(x) # => 43
+
+def set_global_x(num):
global x
- print (x) # => 5
- x = num # Глобальная переменная x теперь равна 6
- print (x) # => 6
+ print(x) # => 5
+ x = num # Глобальная переменная x теперь равна 6
+ print(x) # => 6
-setX(43)
-setGlobalX(6)
+set_x(43)
+set_global_x(6)
-# В Python функции — «объекты первого класса»
+# Python имеет функции первого класса
def create_adder(x):
def adder(y):
return x + y
return adder
add_10 = create_adder(10)
-add_10(3) #=> 13
+add_10(3) # => 13
# Также есть и анонимные функции
-(lambda x: x > 2)(3) #=> True
+(lambda x: x > 2)(3) # => True
+(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
# Есть встроенные функции высшего порядка
-map(add_10, [1,2,3]) #=> [11, 12, 13]
-filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+list(map(add_10, [1, 2, 3])) # => [11, 12, 13]
+list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3]
+
+list(filter(lambda x: x > 5, [3, 4, 5, 6, 7])) # => [6, 7]
+
+# Для удобного отображения и фильтрации можно использовать списочные интерпретации
+# Интерпретация списка сохраняет вывод в виде списка, который сам может быть вложенным списком
+[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
+
+# Вы также можете создавать интерпретации множеств и словарей.
+{x for x in 'abcddeef' if x not in 'abc'} # => {'d', 'e', 'f'}
+{x: x**2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
-# Для удобного отображения и фильтрации можно использовать списочные включения
-[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
-[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
####################################################
-## 5. Классы
+## 5. Модули
####################################################
-# Чтобы получить класс, мы наследуемся от object.
-class Human(object):
+# Вы можете импортировать модули
+import math
+print(math.sqrt(16)) # => 4.0
+
+# Вы можете получить определенные функции из модуля
+from math import ceil, floor
+print(ceil(3.7)) # => 4.0
+print(floor(3.7)) # => 3.0
+
+# Вы можете импортировать все функции из модуля.
+# Предупреждение: это не рекомендуется
+from math import *
+
+# Вы можете сократить имена модулей
+import math as m
+math.sqrt(16) == m.sqrt(16) # => True
- # Атрибут класса. Он разделяется всеми экземплярами этого класса
- species = "H. sapiens"
+# Модули Python - это обычные файлы Python. Вы
+# можете писать свои собственные и импортировать их. Имя
+# модуля совпадает с именем файла.
+
+# Вы можете узнать, какие функции и атрибуты
+# определены в модуле.
+import math
+dir(math)
+
+# Если у вас есть скрипт Python с именем math.py в той же папке,
+# что и ваш текущий скрипт, файл math.py будет
+# будет загружен вместо встроенного модуля Python.
+# Это происходит потому, что локальная папка имеет приоритет
+# над встроенными библиотеками Python.
+
+
+####################################################
+## 6. Классы
+####################################################
+
+# Мы используем оператор class для создания класса
+class Human:
+
+ # Атрибут класса. Он используется всеми экземплярами этого класса
+ species = "Гомосапиенс"
# Обычный конструктор, вызывается при инициализации экземпляра класса
# Обратите внимание, что двойное подчёркивание в начале и в конце имени
# означает объекты и атрибуты, которые используются Python, но находятся
# в пространствах имён, управляемых пользователем.
+ # Методы (или объекты или атрибуты), например:
+ # __init__, __str__, __repr__ и т. д. называются специальными методами.
# Не придумывайте им имена самостоятельно.
def __init__(self, name):
- # Присваивание значения аргумента атрибуту класса name
+ # Присваивание значения аргумента атрибуту
self.name = name
+ # Инициализация свойства
+ self._age = 0
+
# Метод экземпляра. Все методы принимают self в качестве первого аргумента
def say(self, msg):
return "{name}: {message}".format(name=self.name, message=msg)
+ # Другой метод экземпляра
+ def sing(self):
+ return 'йо... йо... проверка микрофона... раз, два... раз, два...'
+
# Метод класса разделяется между всеми экземплярами
# Они вызываются с указыванием вызывающего класса в качестве первого аргумента
@classmethod
@@ -526,55 +742,242 @@ class Human(object):
def grunt():
return "*grunt*"
+ # property похоже на геттер.
+ # Оно превращает метод age() в одноименный атрибут только для чтения.
+ # Однако нет необходимости писать тривиальные геттеры и сеттеры в Python.
+ @property
+ def age(self):
+ return self._age
+
+ # Это позволяет установить свойство
+ @age.setter
+ def age(self, age):
+ self._age = age
+
+ # Это позволяет удалить свойство
+ @age.deleter
+ def age(self):
+ del self._age
+
+
+# Когда интерпретатор Python читает исходный файл, он выполняет весь его код.
+# Проверка __name__ гарантирует, что этот блок кода выполняется только тогда, когда
+# этот модуль - это основная программа.
+if __name__ == '__main__':
+ # Инициализация экземпляра класса
+ i = Human(name="Иван")
+ i.say("привет") # Выводит: "Иван: привет"
+ j = Human("Пётр")
+ j.say("привет") # Выводит: "Пётр: привет"
+ # i и j являются экземплярами типа Human, или другими словами: они являются объектами Human
+
+ # Вызов метода класса
+ i.say(i.get_species()) # "Иван: Гомосапиенс"
+ # Изменение разделяемого атрибута
+ Human.species = "Неандертальец"
+ i.say(i.get_species()) # => "Иван: Неандертальец"
+ j.say(j.get_species()) # => "Пётр: Неандертальец"
+
+ # Вызов статического метода
+ print(Human.grunt()) # => "*grunt*"
+
+ # Невозможно вызвать статический метод с экземпляром объекта
+ # потому что i.grunt() автоматически поместит "self" (объект i) в качестве аргумента
+ print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
+
+ # Обновить свойство для этого экземпляра
+ i.age = 42
+ # Получить свойство
+ i.say(i.age) # => "Иван: 42"
+ j.say(j.age) # => "Пётр: 0"
+ # Удалить свойство
+ del i.age
+ # i.age # => это выбрасило бы ошибку AttributeError
+
+
+####################################################
+## 6.1 Наследование
+####################################################
+
+# Наследование позволяет определять новые дочерние классы, которые наследуют методы и
+# переменные от своего родительского класса.
+
+# Используя класс Human, определенный выше как базовый или родительский класс, мы можем
+# определить дочерний класс Superhero, который наследует переменные класса, такие как
+# "species", "name" и "age", а также методы, такие как "sing" и "grunt" из класса Human,
+# но также может иметь свои уникальные свойства.
+
+# Чтобы воспользоваться преимуществами модульности по файлам, вы можете поместить
+# вышеперечисленные классы в их собственные файлы, например, human.py
+
+# Чтобы импортировать функции из других файлов, используйте следующий формат
+# from "имя-файла-без-расширения" import "функция-или-класс"
+
+from human import Human
+
+
+# Укажите родительский класс(ы) как параметры определения класса
+class Superhero(Human):
+
+ # Если дочерний класс должен наследовать все определения родителя без каких-либо
+ # изменений, вы можете просто использовать ключевое слово pass (и ничего больше),
+ # но в этом случае оно закомментировано, чтобы разрешить уникальный дочерний класс:
+ # pass
+
+ # Дочерние классы могут переопределять атрибуты своих родителей
+ species = 'Сверхчеловек'
+
+ # Дочерние классы автоматически наследуют конструктор родительского класса, включая
+ # его аргументы, но также могут определять дополнительные аргументы или определения
+ # и переопределять его методы, такие как конструктор класса.
+ # Этот конструктор наследует аргумент "name" от класса "Human"
+ # и добавляет аргументы "superpower" и "movie":
+ def __init__(self, name, movie=False,
+ superpowers=["сверхсила", "пуленепробиваемость"]):
+
+ # добавить дополнительные атрибуты класса:
+ self.fictional = True
+ self.movie = movie
+ # помните об изменяемых значениях по умолчанию,
+ # поскольку значения по умолчанию являются общими
+ self.superpowers = superpowers
+
+ # Функция "super" позволяет вам получить доступ к методам родительского класса,
+ # которые переопределяются дочерним, в данном случае, методом __init__.
+ # Это вызывает конструктор родительского класса:
+ super().__init__(name)
+
+ # переопределить метод sing
+ def sing(self):
+ return 'Бам, бам, БАМ!'
+
+ # добавить дополнительный метод экземпляра
+ def boast(self):
+ for power in self.superpowers:
+ print("Я обладаю силой '{pow}'!".format(pow=power))
+
+
+if __name__ == '__main__':
+ sup = Superhero(name="Тик")
-# Инициализация экземпляра класса
-i = Human(name="Иван")
-print(i.say("привет")) # Выводит: «Иван: привет»
+ # Проверка типа экземпляра
+ if isinstance(sup, Human):
+ print('Я человек')
+ if type(sup) is Superhero:
+ print('Я супергерой')
-j = Human("Пётр")
-print(j.say("Привет")) # Выводит: «Пётр: привет»
+ # Получить порядок поиска разрешения метода (MRO),
+ # используемый как getattr(), так и super()
+ # Этот атрибут является динамическим и может быть обновлен
+ print(Superhero.__mro__) # => (<class '__main__.Superhero'>,
+ # => <class 'human.Human'>, <class 'object'>)
-# Вызов метода класса
-i.get_species() #=> "H. sapiens"
+ # Вызывает родительский метод, но использует свой собственный атрибут класса
+ print(sup.get_species()) # => Сверхчеловек
-# Изменение разделяемого атрибута
-Human.species = "H. neanderthalensis"
-i.get_species() #=> "H. neanderthalensis"
-j.get_species() #=> "H. neanderthalensis"
+ # Вызов переопределенного метода
+ print(sup.sing()) # => Бам, бам, БАМ!
-# Вызов статического метода
-Human.grunt() #=> "*grunt*"
+ # Вызывает метод из Human
+ sup.say('Ложка') # => Тик: Ложка
+
+ # Метод вызова, существующий только в Superhero
+ sup.boast() # => Я обладаю силой 'сверхсила'!
+ # => Я обладаю силой 'пуленепробиваемость'!
+
+ # Атрибут унаследованного класса
+ sup.age = 31
+ print(sup.age) # => 31
+
+ # Атрибут, который существует только в Superhero
+ print('Достоин ли я Оскара? ' + str(sup.movie))
####################################################
-## 6. Модули
+## 6.2 Множественное наследование
####################################################
-# Вы можете импортировать модули
-import math
-print(math.sqrt(16)) #=> 4.0
+# Eще одно определение класса
+# bat.py
+class Bat:
-# Вы можете импортировать отдельные функции модуля
-from math import ceil, floor
-print(ceil(3.7)) #=> 4.0
-print(floor(3.7)) #=> 3.0
+ species = 'Летучая мышь'
-# Можете импортировать все функции модуля.
-# (Хотя это и не рекомендуется)
-from math import *
+ def __init__(self, can_fly=True):
+ self.fly = can_fly
-# Можете сокращать имена модулей
-import math as m
-math.sqrt(16) == m.sqrt(16) #=> True
+ # В этом классе также есть метод say
+ def say(self, msg):
+ msg = '... ... ...'
+ return msg
-# Модули в Python — это обычные Python-файлы. Вы
-# можете писать свои модули и импортировать их. Название
-# модуля совпадает с названием файла.
+ # И свой метод тоже
+ def sonar(self):
+ return '))) ... ((('
+
+if __name__ == '__main__':
+ b = Bat()
+ print(b.say('привет'))
+ print(b.fly)
+
+
+# И еще одно определение класса, унаследованное от Superhero и Bat
+# superhero.py
+from superhero import Superhero
+from bat import Bat
+
+# Определите Batman как дочерний класс, унаследованный от Superhero и Bat
+class Batman(Superhero, Bat):
+
+ def __init__(self, *args, **kwargs):
+ # Обычно для наследования атрибутов необходимо вызывать super:
+ # super(Batman, self).__init__(*args, **kwargs)
+ # Однако здесь мы имеем дело с множественным наследованием, а super()
+ # работает только со следующим базовым классом в списке MRO.
+ # Поэтому вместо этого мы вызываем __init__ для всех родителей.
+ # Использование *args и **kwargs обеспечивает чистый способ передачи
+ # аргументов, когда каждый родитель "очищает слой луковицы".
+ Superhero.__init__(self, 'анонимный', movie=True,
+ superpowers=['Богатый'], *args, **kwargs)
+ Bat.__init__(self, *args, can_fly=False, **kwargs)
+ # переопределить значение атрибута name
+ self.name = 'Грустный Бен Аффлек'
+
+ def sing(self):
+ return 'на на на на на бэтмен!'
+
+
+if __name__ == '__main__':
+ sup = Batman()
+
+ # Получить порядок поиска разрешения метода (MRO),
+ # используемый как getattr(), так и super()
+ # Этот атрибут является динамическим и может быть обновлен
+ print(Batman.__mro__) # => (<class '__main__.Batman'>,
+ # => <class 'superhero.Superhero'>,
+ # => <class 'human.Human'>,
+ # => <class 'bat.Bat'>, <class 'object'>)
+
+ # Вызывает родительский метод, но использует свой собственный атрибут класса
+ print(sup.get_species()) # => Сверхчеловек
+
+ # Вызов переопределенного метода
+ print(sup.sing()) # => на на на на на бэтмен!
+
+ # Вызывает метод из Human, потому что порядок наследования имеет значение
+ sup.say('Я согласен') # => Грустный Бен Аффлек: Я согласен
+
+ # Вызов метода, существующий только во втором родителе
+ print(sup.sonar()) # => ))) ... (((
+
+ # Атрибут унаследованного класса
+ sup.age = 100
+ print(sup.age) # => 100
+
+ # Унаследованный атрибут от второго родителя,
+ # значение по умолчанию которого было переопределено.
+ print('Могу ли я летать? ' + str(sup.fly)) # => Могу ли я летать? False
-# Вы можете узнать, какие функции и атрибуты определены
-# в модуле
-import math
-dir(math)
####################################################
## 7. Дополнительно
@@ -585,27 +988,30 @@ def double_numbers(iterable):
for i in iterable:
yield i + i
-# Генератор создаёт значения на лету.
-# Он не возвращает все значения разом, а создаёт каждое из них при каждой
-# итерации. Это значит, что значения больше 15 в double_numbers
-# обработаны не будут.
-# Обратите внимание: range — это тоже генератор.
-# Создание списка чисел от 1 до 900000000 требует много места и времени.
-# Если нам нужно имя переменной, совпадающее с ключевым словом Python,
-# мы используем подчёркивание в конце
-range_ = range(1, 900000000)
-
-# Будет удваивать все числа, пока результат не превысит 30
-for i in double_numbers(range_):
+# Генераторы эффективны с точки зрения памяти, потому что они загружают только данные,
+# необходимые для обработки следующего значения в итерации.
+# Это позволяет им выполнять операции с недопустимо большими диапазонами значений.
+# ПРИМЕЧАНИЕ: "range" заменяет "xrange" в Python 3.
+for i in double_numbers(range(1, 900000000)): # "range" - генератор.
print(i)
if i >= 30:
break
+# Так же, как вы можете создать интерпретации списков, вы можете создать и
+# интерпретации генераторов.
+values = (-x for x in [1,2,3,4,5])
+for x in values:
+ print(x) # Выводит -1 -2 -3 -4 -5
+
+# Вы также можете преобразовать интерпретацию генератора непосредственно в список.
+values = (-x for x in [1,2,3,4,5])
+gen_to_list = list(values)
+print(gen_to_list) # => [-1, -2, -3, -4, -5]
+
# Декораторы
-# В этом примере beg оборачивает say
-# Метод beg вызовет say. Если say_please равно True,
-# он изменит возвращаемое сообщение
+# В этом примере "beg" оборачивает "say".
+# Если say_please равно True, он изменит возвращаемое сообщение.
from functools import wraps
@@ -614,7 +1020,7 @@ def beg(target_function):
def wrapper(*args, **kwargs):
msg, say_please = target_function(*args, **kwargs)
if say_please:
- return "{} {}".format(msg, " Пожалуйста! У меня нет денег :(")
+ return "{} {}".format(msg, "Пожалуйста! У меня нет денег :(")
return msg
return wrapper
@@ -626,8 +1032,8 @@ def say(say_please=False):
return msg, say_please
-print(say()) # Вы не купите мне пива?
-print(say(say_please=True)) # Вы не купите мне пива? Пожалуйста! У меня нет денег :(
+print(say()) # Вы не купите мне пива?
+print(say(say_please=True)) # Вы не купите мне пива? Пожалуйста! У меня нет денег :(
```
@@ -635,17 +1041,18 @@ print(say(say_please=True)) # Вы не купите мне пива? Пожал
### Бесплатные онлайн-материалы
-* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
-* [Dive Into Python](http://www.diveintopython.net/)
+* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
* [Ideas for Python Projects](http://pythonpracticeprojects.com)
* [Официальная документация](http://docs.python.org/3/)
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
-* [Python Module of the Week](http://pymotw.com/3/)
-* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
-
-### Платные
-
-* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
-* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
-* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+* [Python Course](http://www.python-course.eu/index.php)
+* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
+* [A curated list of awesome Python frameworks, libraries and software](https://github.com/vinta/awesome-python)
+* [30 Python Language Features and Tricks You May Not Know About](http://sahandsaba.com/thirty-python-language-features-and-tricks-you-may-not-know.html)
+* [Official Style Guide for Python](https://www.python.org/dev/peps/pep-0008/)
+* [Python 3 Computer Science Circles](http://cscircles.cemc.uwaterloo.ca/)
+* [Dive Into Python 3](http://www.diveintopython3.net/index.html)
+* [A Crash Course in Python for Scientists](http://nbviewer.jupyter.org/gist/anonymous/5924718)
+* [Python Tutorial for Intermediates](https://pythonbasics.org/)
+* [Build a Desktop App with Python](https://pythonpyqt.com/)
diff --git a/ru-ru/ruby-ru.html.markdown b/ru-ru/ruby-ru.html.markdown
index b1fd04e1..8b263be6 100644
--- a/ru-ru/ruby-ru.html.markdown
+++ b/ru-ru/ruby-ru.html.markdown
@@ -480,7 +480,7 @@ class Human
@name
end
- # Тоже самое можно определить с помощью att_accessor
+ # Тоже самое можно определить с помощью attr_accessor
attr_accessor :name
# Также можно создать методы только для записи или чтения