diff options
author | Dimitris Kokkonis <kokkonisd@gmail.com> | 2020-10-10 12:31:09 +0200 |
---|---|---|
committer | Dimitris Kokkonis <kokkonisd@gmail.com> | 2020-10-10 12:31:09 +0200 |
commit | 916dceba25fcca6d7d9858d25c409bc9984c5fce (patch) | |
tree | fb9e604256d3c3267e0f55de39e0fa3b4b0b0728 /ru-ru | |
parent | 922fc494bcce6cb53d80a5c2c9c039a480c82c1f (diff) | |
parent | 33cd1f57ef49f4ed0817e906b7579fcf33c253a1 (diff) |
Merge remote-tracking branch 'upstream/master' into master
Diffstat (limited to 'ru-ru')
-rw-r--r-- | ru-ru/c++-ru.html.markdown | 21 | ||||
-rw-r--r-- | ru-ru/c-ru.html.markdown | 10 | ||||
-rw-r--r-- | ru-ru/go-ru.html.markdown | 4 | ||||
-rw-r--r-- | ru-ru/javascript-ru.html.markdown | 4 | ||||
-rw-r--r-- | ru-ru/kotlin-ru.html.markdown | 2 | ||||
-rw-r--r-- | ru-ru/nim-ru.html.markdown | 254 | ||||
-rw-r--r-- | ru-ru/pascal-ru.html.markdown | 217 | ||||
-rw-r--r-- | ru-ru/perl-ru.html.markdown | 30 | ||||
-rw-r--r-- | ru-ru/python-ru.html.markdown | 1041 | ||||
-rw-r--r-- | ru-ru/pythonlegacy-ru.html.markdown (renamed from ru-ru/python3-ru.html.markdown) | 226 | ||||
-rw-r--r-- | ru-ru/ruby-ru.html.markdown | 12 | ||||
-rw-r--r-- | ru-ru/rust-ru.html.markdown | 61 | ||||
-rw-r--r-- | ru-ru/sql-ru.html.markdown | 120 | ||||
-rw-r--r-- | ru-ru/yaml-ru.html.markdown | 4 |
14 files changed, 1382 insertions, 624 deletions
diff --git a/ru-ru/c++-ru.html.markdown b/ru-ru/c++-ru.html.markdown index 35994749..3acfafa3 100644 --- a/ru-ru/c++-ru.html.markdown +++ b/ru-ru/c++-ru.html.markdown @@ -43,11 +43,11 @@ int main(int argc, char** argv) // Аргументы командной строки, переданные в программу, хранятся в переменных // argc и argv, так же, как и в C. // argc указывает на количество аргументов, - // а argv является массивом C-подобных строк (char*), который непосредсвенно + // а argv является массивом C-подобных строк (char*), который непосредственно // содержит аргументы. // Первым аргументом всегда передается имя программы. - // argc и argv могут быть опущены, если вы не планируете работать с аругментами - // коммандной строки. + // argc и argv могут быть опущены, если вы не планируете работать с аргументами + // командной строки. // Тогда сигнатура функции будет иметь следующий вид: int main() // Возвращаемое значение 0 указывает на успешное завершение программы. @@ -162,7 +162,7 @@ void foo() int main() { - // Включает все функци из пространства имен Second в текущую область видимости. + // Включает все функции из пространства имен Second в текущую область видимости. // Обратите внимание, что простой вызов foo() больше не работает, // так как теперь не ясно, вызываем ли мы foo из пространства имен Second, или // из глобальной области видимости. @@ -471,6 +471,7 @@ int main() { // членам\методам без открытых или защищенных методов для этого. class OwnedDog : public Dog { +public: void setOwner(const std::string& dogsOwner); // Переопределяем поведение функции печати для всех OwnedDog. Смотрите @@ -582,10 +583,10 @@ public: // Во время компиляции компилятор фактически генерирует копии каждого шаблона // с замещенными параметрами, поэтому полное определение класса должно присутствовать -// при каждом вызове. Именно поэтому классы шаблонов полностью определены в +// при каждом вызове. Именно поэтому шаблоны классов полностью определены в // заголовочных файлах. -// Чтобы создать экземпляр класса шаблона на стеке: +// Чтобы создать экземпляр шаблона класса на стеке: Box<int> intBox; // и вы можете использовать его, как и ожидалось: @@ -605,7 +606,7 @@ boxOfBox.insert(intBox); // http://en.wikipedia.org/wiki/Typename // (да-да, это ключевое слово имеет собственную страничку на вики). -// Аналогичным образом, шаблонная функция: +// Аналогичным образом, шаблон функции: template<class T> void barkThreeTimes(const T& input) { @@ -622,7 +623,7 @@ Dog fluffy; fluffy.setName("Fluffy"); barkThreeTimes(fluffy); // Печатает "Fluffy barks" три раза. -//Параметры шаблона не должны быть классами: +// Параметры шаблона не должны быть классами: template<int Y> void printMessage() { cout << "Learn C++ in " << Y << " minutes!" << endl; @@ -680,7 +681,7 @@ catch (...) // некоторого ресурса неразрывно совмещается с инициализацией, а освобождение - // с уничтожением объекта. -// Чтобы понять, на сколько это полезно, +// Чтобы понять, насколько это полезно, // рассмотрим функцию, которая использует обработчик файлов в С: void doSomethingWithAFile(const char* filename) { @@ -796,7 +797,7 @@ void doSomethingWithAFile(const std::string& filename) // - Контейнеры - стандартная библиотека связанных списков, векторы // (т.е. самоизменяемые массивы), хэш-таблицы и все остальное автоматически // уничтожается сразу же, когда выходит за пределы области видимости. -// - Ипользование мьютексов lock_guard и unique_lock +// - Использование мьютексов lock_guard и unique_lock // Контейнеры с пользовательскими классами в качестве ключей требуют // сравнивающих функций в самом объекте или как указатель на функцию. Примитивы diff --git a/ru-ru/c-ru.html.markdown b/ru-ru/c-ru.html.markdown index 44e7ad3b..ba3c19ee 100644 --- a/ru-ru/c-ru.html.markdown +++ b/ru-ru/c-ru.html.markdown @@ -77,7 +77,7 @@ int main() { // sizeof(obj) возвращает размер объекта obj в байтах. printf("%zu\n", sizeof(int)); // => 4 (на большинстве машин int занимает 4 байта) - // Если аргуметом sizeof будет выражение, то этот аргумент вычисляется + // Если аргументом sizeof будет выражение, то этот аргумент вычисляется // ещё во время компиляции кода (кроме динамических массивов). int a = 1; // size_t это беззнаковый целый тип который использует как минимум 2 байта @@ -308,7 +308,7 @@ int main() { // Это работает, потому что при обращении к имени массива возвращается // указатель на первый элемент. // Например, когда массив передаётся в функцию или присваивается указателю, он - // неяввно преобразуется в указатель. + // неявно преобразуется в указатель. // Исключения: когда массив является аргументом для оператор '&': int arr[10]; int (*ptr_to_arr)[10] = &arr; // &arr не является 'int *'! @@ -335,7 +335,7 @@ int main() { // Работа с памятью с помощью указателей может давать неожиданные и // непредсказуемые результаты. - printf("%d\n", *(my_ptr + 21)); // => Напечатает кто-нибудь-знает-что? + printf("%d\n", *(my_ptr + 21)); // => Напечатает кто-нибудь знает, что? // Скорей всего программа вылетит. // Когда вы закончили работать с памятью, которую ранее выделили, вам необходимо @@ -426,7 +426,7 @@ void function_1() { // Можно получить доступ к структуре и через указатель (*my_rec_ptr).width = 30; - // ... или ещё лучше: используйте оператор -> для лучшей читабельночти + // ... или ещё лучше: используйте оператор -> для лучшей читабельности my_rec_ptr->height = 10; // то же что и "(*my_rec_ptr).height = 10;" } @@ -471,7 +471,7 @@ void str_reverse_through_pointer(char *str_in) { Лучше всего найдите копию [K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language) Это **книга** написанная создателями Си. Но будьте осторожны, она содержит идеи которые больше не считаются хорошими. -Другой хороший ресурс: [Learn C the hard way](http://c.learncodethehardway.org/book/). +Другой хороший ресурс: [Learn C the hard way](http://learncodethehardway.org/c/). Если у вас появился вопрос, почитайте [compl.lang.c Frequently Asked Questions](http://c-faq.com). diff --git a/ru-ru/go-ru.html.markdown b/ru-ru/go-ru.html.markdown index 6c8622cc..37592258 100644 --- a/ru-ru/go-ru.html.markdown +++ b/ru-ru/go-ru.html.markdown @@ -35,7 +35,7 @@ package main // Import предназначен для указания зависимостей этого файла. import ( "fmt" // Пакет в стандартной библиотеке Go - "io/ioutil" // Реализация функций ввод/ввывода. + "io/ioutil" // Реализация функций ввод/вывода. "net/http" // Да, это веб-сервер! "strconv" // Конвертирование типов в строки и обратно m "math" // Импортировать math под локальным именем m. @@ -270,7 +270,7 @@ func learnErrorHandling() { // c – это тип данных channel (канал), объект для конкурентного взаимодействия. func inc(i int, c chan int) { - c <- i + 1 // когда channel слева, <- являтся оператором "отправки". + c <- i + 1 // когда channel слева, <- является оператором "отправки". } // Будем использовать функцию inc для конкурентной инкрементации чисел. diff --git a/ru-ru/javascript-ru.html.markdown b/ru-ru/javascript-ru.html.markdown index 1f1ffce6..c31c6994 100644 --- a/ru-ru/javascript-ru.html.markdown +++ b/ru-ru/javascript-ru.html.markdown @@ -1,7 +1,7 @@ --- language: javascript contributors: - - ["Adam Brenecki", "http://adam.brenecki.id.au"] + - ["Leigh Brenecki", "https://leigh.net.au"] - ["Ariel Krakowski", "http://www.learneroo.com"] filename: javascript-ru.js translators: @@ -420,7 +420,7 @@ myObj.__proto__ = myPrototype; myObj.meaningOfLife; // = 42 // Для функций это тоже работает. -myObj.myFunc(); // = "Привет, мир!" +myObj.myFunc(); // = "привет, мир!" // Если интерпретатор не найдёт свойство в прототипе, то продожит поиск // в прототипе прототипа и так далее. diff --git a/ru-ru/kotlin-ru.html.markdown b/ru-ru/kotlin-ru.html.markdown index 58dab4cd..85f44c96 100644 --- a/ru-ru/kotlin-ru.html.markdown +++ b/ru-ru/kotlin-ru.html.markdown @@ -8,7 +8,7 @@ translators: - ["Vadim Toptunov", "https://github.com/VadimToptunov"] --- -Kotlin - статистически типизированный язык для JVM, Android и браузера. Язык полностью совместим c Java. +Kotlin - статически типизированный язык для JVM, Android и браузера. Язык полностью совместим c Java. [Более детальная информация здесь.](https://kotlinlang.org/) ```kotlin 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 6087a686..e0e53b9c 100644 --- a/ru-ru/python-ru.html.markdown +++ b/ru-ru/python-ru.html.markdown @@ -1,27 +1,30 @@ --- -language: python +language: Python lang: ru-ru contributors: - ["Louie Dinh", "http://ldinh.ca"] + - ["Steven Basart", "http://github.com/xksteven"] translators: - - ["Yury Timofeev", "http://twitter.com/gagar1n"] - ["Andre Polykanine", "https://github.com/Oire"] + - ["Anton Grouchtchak", "https://github.com/Teraskull"] filename: learnpython-ru.py --- Язык Python был создан Гвидо ван Россумом в начале 90-х. Сейчас это один из самых популярных языков. Я влюбился в Python за понятный и доходчивый синтаксис — это -почти исполняемый псевдокод. +почти что исполняемый псевдокод. С благодарностью жду ваших отзывов: [@louiedinh](http://twitter.com/louiedinh) или louiedinh [at] [почтовый сервис Google] -Замечание: Эта статья относится к Python 2.7, но должно работать и в других версиях Python 2.x. -Чтобы изучить Python 3.x, обратитесь к статье по Python 3. +Замечание: Эта статья относится только к Python 3. +Если вы хотите изучить Python 2.7, обратитесь к другой статье. ```python + # Однострочные комментарии начинаются с символа решётки. -""" Многострочный текст может быть + +""" Многострочный текст может быть записан, используя 3 знака " и обычно используется в качестве встроенной документации """ @@ -31,323 +34,397 @@ filename: learnpython-ru.py #################################################### # У вас есть числа -3 #=> 3 +3 # => 3 # Математика работает вполне ожидаемо -1 + 1 #=> 2 -8 - 1 #=> 7 -10 * 2 #=> 20 -35 / 5 #=> 7 - -# А вот деление немного сложнее. В этом случае происходит деление -# целых чисел, и результат автоматически округляется в меньшую сторону. -5 / 2 #=> 2 - -# Чтобы делить правильно, сначала нужно немного узнать о числах -# с плавающей запятой. -2.0 # Это число с плавающей запятой -11.0 / 4.0 #=> 2.75 Вооот... Так гораздо лучше +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 +# # Результат деления возвращает число с плавающей запятой +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 -# Логические операторы -# Обратите внимание: ключевые слова «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 +# Булевы значения - примитивы (Обратите внимание на заглавную букву) +True # => True +False # => False # Для отрицания используется ключевое слово not -not True #=> False -not False #=> 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 равны # Строки определяются символом " или ' "Это строка." 'Это тоже строка.' -# И строки тоже можно складывать! -"Привет " + "мир!" #=> "Привет мир!" +# И строки тоже могут складываться! Хотя лучше не злоупотребляйте этим. +"Привет " + "мир!" # => "Привет мир!" -# ... или умножать -"Привет" * 3 # => "ПриветПриветПривет" +# Строки (но не переменные) могут быть объединены без использования '+' +"Привет " "мир!" # => "Привет мир!" # Со строкой можно работать, как со списком символов -"Это строка"[0] #=> 'Э' +"Привет мир!"[0] # => 'П' -# Символ % используется для форматирования строк, например: -"%s могут быть %s" % ("строки", "интерполированы") +# Вы можете найти длину строки +len("Это строка") # => 10 -# Новый способ форматирования строк — использование метода format. -# Это предпочитаемый способ. -"{0} могут быть {1}".format("строки", "форматированы") +# Вы также можете форматировать, используя f-строки (в Python 3.6+) +name = "Рейко" +f"Она сказала, что ее зовут {name}." # => "Она сказала, что ее зовут Рейко" +# Вы можете поместить любой оператор Python в фигурные скобки, и он будет выведен в строке. +f"{name} состоит из {len(name)} символов." # => "Рэйко состоит из 5 символов." -# Если вы не хотите считать, можете использовать ключевые слова. -"{name} хочет есть {food}".format(name="Боб", food="лазанью") # 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 -0 == False #=> True -"" == False #=> True +bool(0) # => False +bool("") # => False +bool([]) # => False +bool({}) # => False +bool(()) # => False #################################################### -## 2. Переменные и коллекции +## 2. Переменные и Коллекции #################################################### -# В Python есть оператор print, доступный в версиях 2.x, но удалённый в версии 3 -print "Я Python. Приятно познакомиться!" -# В Python также есть функция print(), доступная в версиях 2.7 и 3, -# Но для версии 2.7 нужно добавить следующий импорт модуля (раскомментируйте)): -# from __future__ import print_function -print("Я тоже Python! ") +# В Python есть функция Print +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_var # => 5 -# При попытке доступа к неинициализированной переменной -# выбрасывается исключение. -# См. раздел «Поток управления» для информации об исключениях. -some_other_var # Выбрасывает ошибку именования +# При попытке доступа к неинициализированной переменной выбрасывается исключение. +# Об исключениях см. раздел "Поток управления и итерируемые объекты". +some_unknown_var # Выбрасывает ошибку NameError -# if может быть использован как выражение -"yahoo!" if 3 > 2 else 2 #=> "yahoo!" +# if можно использовать как выражение +# Эквивалент тернарного оператора '?:' в C +"да!" if 0 > 1 else "нет!" # => "нет!" # Списки хранят последовательности li = [] # Можно сразу начать с заполненного списка other_li = [4, 5, 6] -# строка разделена в список -a="adambard" -list(a) #=> ['a','d','a','m','b','a','r','d'] - -# Объекты добавляются в конец списка методом 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] = 42 -li[0] # => 42 -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] # li теперь [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 #=> [1, 2, 3, 4, 5, 6] — Замечание: li и other_li не изменяются # Обратите внимание: значения 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]} # Однако значения могут быть любого типа. + +# Поиск значений с помощью [] +filled_dict["one"] # => 1 -# Можно получить все ключи в виде списка с помощью метода keys -filled_dict.keys() #=> ["three", "two", "one"] -# Замечание: сохранение порядка ключей в словаре не гарантируется -# Ваши результаты могут не совпадать с этими. +# Все ключи в виде списка получаются с помощью метода keys(). +# Его вызов нужно обернуть в list(), так как обратно мы получаем +# итерируемый объект, о которых поговорим позднее. Примечание - для 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 -filled_dict.values() #=> [3, 2, 1] + +# Все значения в виде списка можно получить с помощью values(). +# И снова нам нужно обернуть вызов в list(), чтобы превратить +# итерируемый объект в список. # То же самое замечание насчёт порядка ключей справедливо и здесь +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("four") всё ещё => None -# (get не устанавливает значение элемента словаря) - -# Присваивайте значение ключам так же, как и в списках -filled_dict["four"] = 4 # теперь filled_dict["four"] => 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 +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 # Другой способ добавления элементов + +# Удаляйте ключи из словаря с помощью ключевого слова del +del filled_dict["one"] # Удаляет ключ "one" из словаря + +# После Python 3.5 вы также можете использовать дополнительные параметры распаковки +{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2} +{'a': 1, **{'a': 2}} # => {'a': 2} + # Множества содержат... ну, в общем, множества -# (которые похожи на списки, только в них не может быть дублирующихся элементов) empty_set = set() -# Инициализация множества набором значений -some_set = set([1,2,2,3,4]) # some_set теперь равно set([1, 2, 3, 4]) - -# Порядок сортировки не гарантируется, хотя иногда они выглядят отсортированными -another_set = set([4, 3, 2, 2, 1]) # another_set теперь set([1, 2, 3, 4]) +# Инициализация множества набором значений. +# Да, оно выглядит примерно как словарь. Ну извините, так уж вышло. +filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4} -# Начиная с Python 2.7, вы можете использовать {}, чтобы объявить множество -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.add(5) # filled_set равно {1, 2, 3, 4, 5} +# Множеству можно назначать новую переменную +filled_set = some_set +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} -# Проверка на вхождение во множество: in -2 in filled_set #=> True -10 in filled_set #=> False +# Симметричная разница: ^ +{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5} + +# Проверить, является ли множество слева надмножеством множества справа +{1, 2} >= {1, 2, 3} # => 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. Поток управления +## 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 ["собака", "кошка", "мышь"]: - # Можете использовать оператор % для интерполяции форматированных строк - print("%s — это млекопитающее" % animal) - + # Можете использовать format() для интерполяции форматированных строк + print("{} — это млекопитающее".format(animal)) + """ -«range(число)» возвращает список чисел +"range(число)" возвращает список чисел от нуля до заданного числа -Результат: +Выводит: 0 1 2 @@ -357,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 @@ -370,20 +481,81 @@ while x < 4: x += 1 # Краткая запись для x = x + 1 # Обрабатывайте исключения блоками try/except - -# Работает в Python 2.6 и выше: 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 предоставляет фундаментальную абстракцию, +# которая называется итерируемым объектом (Iterable). +# Итерируемый объект — это объект, который воспринимается как последовательность. +# Объект, который возвратила функция range(), итерируемый. + +filled_dict = {"one": 1, "two": 2, "three": 3} +our_iterable = filled_dict.keys() +print(our_iterable) # => dict_keys(['one', 'two', 'three']). Это объект, реализующий интерфейс Iterable + +# Мы можем проходить по нему циклом. +for i in our_iterable: + print(i) # Выводит one, two, three + +# Но мы не можем обращаться к элементу по индексу. +our_iterable[1] # Выбрасывает ошибку TypeError + +# Итерируемый объект знает, как создавать итератор. +our_iterator = iter(our_iterable) + +# Итератор может запоминать состояние при проходе по объекту. +# Мы получаем следующий объект, вызывая функцию next(). +next(our_iterator) # => "one" +# Он сохраняет состояние при вызове next(). +next(our_iterator) # => "two" +next(our_iterator) # => "three" + +# Возвратив все данные, итератор выбрасывает исключение StopIterator +next(our_iterator) # Выбрасывает исключение StopIteration + +# Мы можем проходить по нему циклом. +our_iterator = iter(our_iterable) +for i in our_iterator: + print(i) # Выводит one, two, three + +# Вы можете получить сразу все элементы итератора, вызвав на нём функцию list(). +list(our_iterable) # => Возвращает ["one", "two", "three"] +list(our_iterator) # => Возвращает [] потому что состояние сохраняется #################################################### @@ -393,30 +565,28 @@ else: # Необязательное выражение. Должно след # Используйте 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) # А также можете определить функцию, принимающую переменное число -# именованных аргументов, которые будут интерпретированы как словарь, -# если вы не используете ** +# именованных аргументов 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): @@ -432,77 +602,134 @@ 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) - -# вы можете передавать переменное число позиционных или именованных аргументов -# другим функциям, которые их принимают, распаковывая их с помощью -# * или ** соответственно -def pass_all_the_args(*args, **kwargs): - all_the_args(*args, **kwargs) - print varargs(*args) - print keyword_args(**kwargs) +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 * - # Атрибут класса. Он разделяется всеми экземплярами этого класса - species = "H. sapiens" +# Вы можете сократить имена модулей +import math as m +math.sqrt(16) == m.sqrt(16) # => True + +# Модули 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 "%s: %s" % (self.name, msg) + return "{name}: {message}".format(name=self.name, message=msg) + + # Другой метод экземпляра + def sing(self): + return 'йо... йо... проверка микрофона... раз, два... раз, два...' # Метод класса разделяется между всеми экземплярами # Они вызываются с указыванием вызывающего класса в качестве первого аргумента @@ -515,58 +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)) + -# Инициализация экземпляра класса -i = Human(name="Иван") -print(i.say("привет")) # Выводит: «Иван: привет» +if __name__ == '__main__': + sup = Superhero(name="Тик") -j = Human("Пётр") -print(j.say("Привет")) # Выводит: «Пётр: привет» + # Проверка типа экземпляра + if isinstance(sup, Human): + print('Я человек') + if type(sup) is Superhero: + print('Я супергерой') -# Вызов метода класса -i.get_species() #=> "H. sapiens" + # Получить порядок поиска разрешения метода (MRO), + # используемый как getattr(), так и super() + # Этот атрибут является динамическим и может быть обновлен + print(Superhero.__mro__) # => (<class '__main__.Superhero'>, + # => <class 'human.Human'>, <class 'object'>) -# Изменение разделяемого атрибута -Human.species = "H. neanderthalensis" -i.get_species() #=> "H. neanderthalensis" -j.get_species() #=> "H. neanderthalensis" + # Вызывает родительский метод, но использует свой собственный атрибут класса + print(sup.get_species()) # => Сверхчеловек -# Вызов статического метода -Human.grunt() #=> "*grunt*" + # Вызов переопределенного метода + print(sup.sing()) # => Бам, бам, БАМ! + + # Вызывает метод из 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 -# Вы также можете убедиться, что функции эквивалентны -from math import sqrt -math.sqrt == m.sqrt == sqrt # => 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. Дополнительно @@ -577,28 +988,30 @@ def double_numbers(iterable): for i in iterable: yield i + i -# Генератор создаёт значения на лету. -# Он не возвращает все значения разом, а создаёт каждое из них при каждой -# итерации. Это значит, что значения больше 15 в double_numbers -# обработаны не будут. -# Обратите внимание: xrange — это генератор, который делает то же, что и range. -# Создание списка чисел от 1 до 900000000 требует много места и времени. -# xrange создаёт объект генератора, а не список сразу, как это делает range. -# Если нам нужно имя переменной, совпадающее с ключевым словом Python, -# мы используем подчёркивание в конце -xrange_ = xrange(1, 900000000) - -# Будет удваивать все числа, пока результат не превысит 30 -for i in double_numbers(xrange_): +# Генераторы эффективны с точки зрения памяти, потому что они загружают только данные, +# необходимые для обработки следующего значения в итерации. +# Это позволяет им выполнять операции с недопустимо большими диапазонами значений. +# ПРИМЕЧАНИЕ: "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 @@ -607,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 @@ -619,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)) # Вы не купите мне пива? Пожалуйста! У меня нет денег :( ``` @@ -628,16 +1041,18 @@ print(say(say_please=True)) # Вы не купите мне пива? Пожал ### Бесплатные онлайн-материалы -* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/) -* [Dive Into Python](http://www.diveintopython.net/) -* [Официальная документация](http://docs.python.org/2.6/) +* [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/2/) -* [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/python3-ru.html.markdown b/ru-ru/pythonlegacy-ru.html.markdown index bf80fed2..ead2af3d 100644 --- a/ru-ru/python3-ru.html.markdown +++ b/ru-ru/pythonlegacy-ru.html.markdown @@ -1,23 +1,23 @@ --- -language: python3 +language: Python 2 (legacy) lang: ru-ru contributors: - ["Louie Dinh", "http://ldinh.ca"] - - ["Steven Basart", "http://github.com/xksteven"] translators: + - ["Yury Timofeev", "http://twitter.com/gagar1n"] - ["Andre Polykanine", "https://github.com/Oire"] -filename: learnpython3-ru.py +filename: learnpythonlegacy-ru.py --- Язык Python был создан Гвидо ван Россумом в начале 90-х. Сейчас это один из самых популярных языков. Я влюбился в Python за понятный и доходчивый синтаксис — это -почти что исполняемый псевдокод. +почти исполняемый псевдокод. С благодарностью жду ваших отзывов: [@louiedinh](http://twitter.com/louiedinh) или louiedinh [at] [почтовый сервис Google] -Замечание: Эта статья относится только к Python 3. -Если вы хотите изучить Python 2.7, обратитесь к другой статье. +Замечание: Эта статья относится к Python 2.7, но должно работать и в других версиях Python 2.x. +Чтобы изучить Python 3.x, обратитесь к статье по Python 3. ```python # Однострочные комментарии начинаются с символа решётки. @@ -37,9 +37,16 @@ filename: learnpython3-ru.py 1 + 1 #=> 2 8 - 1 #=> 7 10 * 2 #=> 20 +35 / 5 #=> 7 -# Кроме деления, которое по умолчанию возвращает число с плавающей запятой -35 / 5 # => 7.0 +# А вот деление немного сложнее. В этом случае происходит деление +# целых чисел, и результат автоматически округляется в меньшую сторону. +5 / 2 #=> 2 + +# Чтобы делить правильно, сначала нужно немного узнать о числах +# с плавающей запятой. +2.0 # Это число с плавающей запятой +11.0 / 4.0 #=> 2.75 Вооот... Так гораздо лучше # Результат целочисленного деления округляется в меньшую сторону # как для положительных, так и для отрицательных чисел. @@ -48,10 +55,6 @@ filename: learnpython3-ru.py -5 // 3 # => -2 -5.0 // 3.0 # => -2.0 -# Когда вы используете числа с плавающей запятой, -# результатом будет также число с плавающей запятой -3 * 2.0 # => 6.0 - # Остаток от деления 7 % 3 # => 1 @@ -61,14 +64,6 @@ filename: learnpython3-ru.py # Приоритет операций указывается скобками (1 + 3) * 2 #=> 8 -# Для логических (булевых) значений существует отдельный примитивный тип -True -False - -# Для отрицания используется ключевое слово not -not True #=> False -not False #=> True - # Логические операторы # Обратите внимание: ключевые слова «and» и «or» чувствительны к регистру букв True and False #=> False @@ -81,6 +76,10 @@ False or True #=> True 2 == True #=> False 1 == True #=> True +# Для отрицания используется ключевое слово not +not True #=> False +not False #=> True + # Равенство — это == 1 == 1 #=> True 2 == 1 #=> False @@ -95,7 +94,7 @@ False or True #=> True 2 <= 2 #=> True 2 >= 2 #=> True -# Сравнения могут быть записаны цепочкой: +# Сравнения могут быть записаны цепочкой! 1 < 2 < 3 #=> True 2 < 3 < 2 #=> False @@ -103,70 +102,75 @@ False or True #=> True "Это строка." 'Это тоже строка.' -# И строки тоже могут складываться! Хотя лучше не злоупотребляйте этим. +# И строки тоже можно складывать! "Привет " + "мир!" #=> "Привет мир!" -# Строки можно умножать. -"aa" * 4 #=> "aaaaaaaa" +# ... или умножать +"Привет" * 3 # => "ПриветПриветПривет" # Со строкой можно работать, как со списком символов "Это строка"[0] #=> 'Э' -# Метод format используется для форматирования строк: +# Символ % используется для форматирования строк, например: +"%s могут быть %s" % ("строки", "интерполированы") + +# Новый способ форматирования строк — использование метода format. +# Это предпочитаемый способ. "{0} могут быть {1}".format("строки", "форматированы") -# Вы можете повторять аргументы форматирования, чтобы меньше печатать. -"Ехал {0} через реку, видит {0} - в реке {1}! Сунул {0} руку в реку, {1} за руку греку цап!".format("грека", "рак") -#=> "Ехал грека через реку, видит грека - в реке рак! Сунул грека руку в реку, рак за руку греку цап!" # Если вы не хотите считать, можете использовать ключевые слова. "{name} хочет есть {food}".format(name="Боб", food="лазанью") -# Если ваш код на Python 3 нужно запускать также и под Python 2.5 и ниже, -# вы также можете использовать старый способ форматирования: -"%s можно %s %s способом" % ("строки", "интерполировать", "старым") - # None является объектом None #=> None -# Не используйте оператор равенства '==' для сравнения -# объектов с None. Используйте для этого 'is' +# Не используйте оператор равенства '=='' для сравнения +# объектов с None. Используйте для этого «is» "etc" is None #=> False None is None #=> True -# Оператор «is» проверяет идентичность объектов. Он не +# Оператор 'is' проверяет идентичность объектов. Он не # очень полезен при работе с примитивными типами, но # зато просто незаменим при работе с объектами. -# None, 0 и пустые строки/списки/словари приводятся к False. +# None, 0 и пустые строки/списки равны False. # Все остальные значения равны True -bool(0) # => False -bool("") # => False -bool([]) #=> False -bool({}) #=> False +0 == False #=> True +"" == False #=> True #################################################### ## 2. Переменные и коллекции #################################################### -# В Python есть функция Print -print("Я Python. Приятно познакомиться!") +# В Python есть оператор print, доступный в версиях 2.x, но удалённый в версии 3 +print "Я Python. Приятно познакомиться!" +# В Python также есть функция print(), доступная в версиях 2.7 и 3, +# Но для версии 2.7 нужно добавить следующий импорт модуля (раскомментируйте)): +# from __future__ import print_function +print("Я тоже Python! ") # Объявлять переменные перед инициализацией не нужно. -# По соглашению используется нижний_регистр_с_подчёркиваниями -some_var = 5 +some_var = 5 # По соглашению используется нижний_регистр_с_подчёркиваниями some_var #=> 5 # При попытке доступа к неинициализированной переменной # выбрасывается исключение. -# Об исключениях см. раздел «Поток управления и итерируемые объекты». -some_unknown_var # Выбрасывает ошибку именования +# См. раздел «Поток управления» для информации об исключениях. +some_other_var # Выбрасывает ошибку именования + +# if может быть использован как выражение +"yahoo!" if 3 > 2 else 2 #=> "yahoo!" # Списки хранят последовательности li = [] # Можно сразу начать с заполненного списка other_li = [4, 5, 6] +# строка разделена в список +a="adambard" +list(a) #=> ['a','d','a','m','b','a','r','d'] + # Объекты добавляются в конец списка методом append li.append(1) # [1] li.append(2) # [1, 2] @@ -179,6 +183,10 @@ li.append(3) # [1, 2, 4, 3]. # Обращайтесь со списком, как с обычным массивом li[0] #=> 1 +# Присваивайте новые значения уже инициализированным индексам с помощью = +li[0] = 42 +li[0] # => 42 +li[0] = 1 # Обратите внимание: возвращаемся на исходное значение # Обратимся к последнему элементу li[-1] #=> 3 @@ -200,11 +208,11 @@ li[::-1] # => [3, 4, 2, 1] # li[начало:конец:шаг] # Удаляем произвольные элементы из списка оператором del -del li[2] # [1, 2, 3] +del li[2] # li теперь [1, 2, 3] # Вы можете складывать, или, как ещё говорят, конкатенировать списки -# Обратите внимание: значения li и other_li при этом не изменились. li + other_li #=> [1, 2, 3, 4, 5, 6] — Замечание: li и other_li не изменяются +# Обратите внимание: значения li и other_li при этом не изменились. # Объединять списки можно методом extend li.extend(other_li) # Теперь li содержит [1, 2, 3, 4, 5, 6] @@ -234,7 +242,6 @@ d, e, f = 4, 5, 6 # Обратите внимание, как легко поменять местами значения двух переменных e, d = d, e # теперь d == 5, а e == 4 - # Словари содержат ассоциативные массивы empty_dict = {} # Вот так описывается предзаполненный словарь @@ -244,17 +251,13 @@ filled_dict = {"one": 1, "two": 2, "three": 3} # что индекс — у словарей он называется ключом — не обязан быть числом filled_dict["one"] #=> 1 -# Все ключи в виде списка получаются с помощью метода keys(). -# Его вызов нужно обернуть в list(), так как обратно мы получаем -# итерируемый объект, о которых поговорим позднее. -list(filled_dict.keys()) # => ["three", "two", "one"] +# Можно получить все ключи в виде списка с помощью метода keys +filled_dict.keys() #=> ["three", "two", "one"] # Замечание: сохранение порядка ключей в словаре не гарантируется # Ваши результаты могут не совпадать с этими. -# Все значения в виде списка можно получить с помощью values(). -# И снова нам нужно обернуть вызов в list(), чтобы превратить -# итерируемый объект в список. -list(filled_dict.values()) # => [3, 2, 1] +# Можно получить и все значения в виде списка, используйте метод values +filled_dict.values() #=> [3, 2, 1] # То же самое замечание насчёт порядка ключей справедливо и здесь # При помощи оператора in можно проверять ключи на вхождение в словарь @@ -271,27 +274,28 @@ filled_dict.get("four") #=> None # возвращено при отсутствии указанного ключа filled_dict.get("one", 4) #=> 1 filled_dict.get("four", 4) #=> 4 +# Обратите внимание, что filled_dict.get("four") всё ещё => None +# (get не устанавливает значение элемента словаря) + +# Присваивайте значение ключам так же, как и в списках +filled_dict["four"] = 4 # теперь filled_dict["four"] => 4 -# Метод setdefault вставляет пару ключ-значение, только если такого ключа нет +# Метод 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 # Другой способ добавления элементов - -# Удаляйте ключи из словаря с помощью оператора del -del filled_dict["one"] # Удаляет ключ «one» из словаря - # Множества содержат... ну, в общем, множества +# (которые похожи на списки, только в них не может быть дублирующихся элементов) empty_set = set() -# Инициализация множества набором значений. -# Да, оно выглядит примерно как словарь… ну извините, так уж вышло. -filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4} +# Инициализация множества набором значений +some_set = set([1,2,2,3,4]) # some_set теперь равно set([1, 2, 3, 4]) -# Множеству можно назначать новую переменную -filled_set = some_set +# Порядок сортировки не гарантируется, хотя иногда они выглядят отсортированными +another_set = set([4, 3, 2, 2, 1]) # another_set теперь set([1, 2, 3, 4]) + +# Начиная с Python 2.7, вы можете использовать {}, чтобы объявить множество +filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4} # Добавление новых элементов в множество filled_set.add(5) # filled_set равно {1, 2, 3, 4, 5} @@ -312,7 +316,7 @@ filled_set | other_set #=> {1, 2, 3, 4, 5, 6} #################################################### -## 3. Поток управления и итерируемые объекты +## 3. Поток управления #################################################### # Для начала заведём переменную @@ -328,13 +332,17 @@ else: # Это тоже необязательно. print("some_var равно 10.") -# Циклы For проходят по спискам. Результат: - # собака — это млекопитающее - # кошка — это млекопитающее - # мышь — это млекопитающее +""" +Циклы For проходят по спискам + +Результат: + собака — это млекопитающее + кошка — это млекопитающее + мышь — это млекопитающее +""" for animal in ["собака", "кошка", "мышь"]: - # Можете использовать format() для интерполяции форматированных строк - print("{} — это млекопитающее".format(animal)) + # Можете использовать оператор % для интерполяции форматированных строк + print("%s — это млекопитающее" % animal) """ «range(число)» возвращает список чисел @@ -362,6 +370,8 @@ while x < 4: x += 1 # Краткая запись для x = x + 1 # Обрабатывайте исключения блоками try/except + +# Работает в Python 2.6 и выше: try: # Чтобы выбросить ошибку, используется raise raise IndexError("Это ошибка индекса") @@ -374,37 +384,6 @@ except (TypeError, NameError): else: # Необязательное выражение. Должно следовать за последним блоком except print("Всё хорошо!") # Выполнится, только если не было никаких исключений -# Python предоставляет фундаментальную абстракцию, -# которая называется итерируемым объектом (an iterable). -# Итерируемый объект — это объект, который воспринимается как последовательность. -# Объект, который возвратила функция range(), итерируемый. -filled_dict = {"one": 1, "two": 2, "three": 3} -our_iterable = filled_dict.keys() -print(our_iterable) #=> range(1,10). Это объект, реализующий интерфейс iterable - -# Мы можем проходить по нему циклом. -for i in our_iterable: - print(i) # Выводит one, two, three - -# Но мы не можем обращаться к элементу по индексу. -our_iterable[1] # Выбрасывает ошибку типа - -# Итерируемый объект знает, как создавать итератор. -our_iterator = iter(our_iterable) - -# Итератор может запоминать состояние при проходе по объекту. -# Мы получаем следующий объект, вызывая функцию __next__. -our_iterator.__next__() #=> "one" - -# Он сохраняет состояние при вызове __next__. -our_iterator.__next__() #=> "two" -our_iterator.__next__() #=> "three" - -# Возвратив все данные, итератор выбрасывает исключение StopIterator -our_iterator.__next__() # Выбрасывает исключение остановки итератора - -# Вы можете получить сразу все элементы итератора, вызвав на нём функцию list(). -list(filled_dict.keys()) #=> Возвращает ["one", "two", "three"] #################################################### @@ -422,7 +401,8 @@ add(5, 6) #=> выводит «x равен 5, а y равен 6» и возвр # Другой способ вызова функции — вызов с именованными аргументами add(y=6, x=5) # Именованные аргументы можно указывать в любом порядке. -# Вы можете определить функцию, принимающую переменное число аргументов +# Вы можете определить функцию, принимающую переменное число аргументов, +# которые будут интерпретированы как кортеж, если вы не используете * def varargs(*args): return args @@ -430,7 +410,8 @@ varargs(1, 2, 3) #=> (1,2,3) # А также можете определить функцию, принимающую переменное число -# именованных аргументов +# именованных аргументов, которые будут интерпретированы как словарь, +# если вы не используете ** def keyword_args(**kwargs): return kwargs @@ -455,6 +436,14 @@ 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) +# вы можете передавать переменное число позиционных или именованных аргументов +# другим функциям, которые их принимают, распаковывая их с помощью +# * или ** соответственно +def pass_all_the_args(*args, **kwargs): + all_the_args(*args, **kwargs) + print varargs(*args) + print keyword_args(**kwargs) + # Область определения функций x = 5 @@ -513,7 +502,7 @@ class Human(object): # Метод экземпляра. Все методы принимают self в качестве первого аргумента def say(self, msg): - return "{name}: {message}".format(name=self.name, message=msg) + return "%s: %s" % (self.name, msg) # Метод класса разделяется между всеми экземплярами # Они вызываются с указыванием вызывающего класса в качестве первого аргумента @@ -566,6 +555,9 @@ from math import * # Можете сокращать имена модулей import math as m math.sqrt(16) == m.sqrt(16) #=> True +# Вы также можете убедиться, что функции эквивалентны +from math import sqrt +math.sqrt == m.sqrt == sqrt # => True # Модули в Python — это обычные Python-файлы. Вы # можете писать свои модули и импортировать их. Название @@ -589,14 +581,15 @@ def double_numbers(iterable): # Он не возвращает все значения разом, а создаёт каждое из них при каждой # итерации. Это значит, что значения больше 15 в double_numbers # обработаны не будут. -# Обратите внимание: range — это тоже генератор. +# Обратите внимание: xrange — это генератор, который делает то же, что и range. # Создание списка чисел от 1 до 900000000 требует много места и времени. +# xrange создаёт объект генератора, а не список сразу, как это делает range. # Если нам нужно имя переменной, совпадающее с ключевым словом Python, # мы используем подчёркивание в конце -range_ = range(1, 900000000) +xrange_ = xrange(1, 900000000) # Будет удваивать все числа, пока результат не превысит 30 -for i in double_numbers(range_): +for i in double_numbers(xrange_): print(i) if i >= 30: break @@ -637,10 +630,9 @@ print(say(say_please=True)) # Вы не купите мне пива? Пожал * [Learn Python The Hard Way](http://learnpythonthehardway.org/book/) * [Dive Into Python](http://www.diveintopython.net/) -* [Ideas for Python Projects](http://pythonpracticeprojects.com) -* [Официальная документация](http://docs.python.org/3/) +* [Официальная документация](http://docs.python.org/2.6/) * [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/) -* [Python Module of the Week](http://pymotw.com/3/) +* [Python Module of the Week](http://pymotw.com/2/) * [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182) ### Платные diff --git a/ru-ru/ruby-ru.html.markdown b/ru-ru/ruby-ru.html.markdown index e69c6d94..8b263be6 100644 --- a/ru-ru/ruby-ru.html.markdown +++ b/ru-ru/ruby-ru.html.markdown @@ -231,6 +231,7 @@ new_hash.value?(3) #=> true # Управление ходом выполнения (Управляющие структуры) +# Условия if true 'Если истина' elsif false @@ -239,6 +240,15 @@ else 'Во всех других случаях (тоже опционально)' end +# Если условие контролирует выполнение не блока кода, а единственного выражения, +# можно использовать постфиксную запись условного оператора +warnings = ['Отсутствует отчество', 'Слишком короткий адрес'] +puts("Обратите внимание:\n" + warnings.join("\n")) if !warnings.empty? + +# Иногда условие лучше звучит с `unless`, чем с `if` +puts("Обратите внимание:\n" + warnings.join("\n")) unless warnings.empty? + +# Циклы for counter in 1..5 puts "итерация #{counter}" end @@ -470,7 +480,7 @@ class Human @name end - # Тоже самое можно определить с помощью att_accessor + # Тоже самое можно определить с помощью attr_accessor attr_accessor :name # Также можно создать методы только для записи или чтения diff --git a/ru-ru/rust-ru.html.markdown b/ru-ru/rust-ru.html.markdown index 7bd2809a..9293a40e 100644 --- a/ru-ru/rust-ru.html.markdown +++ b/ru-ru/rust-ru.html.markdown @@ -6,36 +6,33 @@ contributors: - ["P1start", "http://p1start.github.io/"] translators: - ["Anatolii Kosorukov", "https://github.com/java1cprog"] + - ["Vasily Starostin", "https://github.com/Basil22"] lang: ru-ru --- -Rust сочетает в себе низкоуровневый контроль над производительностью с удобством высокого уровня и предоставляет гарантии -безопасности. -Он достигает этих целей, не требуя сборщика мусора или времени выполнения, что позволяет использовать библиотеки Rust как замену -для C-библиотек. +Язык Rust разработан в Mozilla Research. Он сочетает низкоуровневую производительность с удобством языка высокого уровня и одновременно гарантирует безопасность памяти. -Первый выпуск Rust, 0.1, произошел в январе 2012 года, и в течение 3 лет развитие продвигалось настолько быстро, что до -недавнего времени использование стабильных выпусков было затруднено, и вместо этого общий совет заключался в том, чтобы -использовать последние сборки. +Он достигает этих целей без сборщика мусора или сложной среды выполнения, что позволяет использовать библиотеки Rust как прямую замену +C-библиотек. И наоборот, Rust умеет использовать готовые С-библиотеки как есть, без накладных расходов. -15 мая 2015 года был выпущен Rust 1.0 с полной гарантией обратной совместимости. Усовершенствования времени компиляции и -других аспектов компилятора в настоящее время доступны в ночных сборках. Rust приняла модель выпуска на поезде с регулярными выпусками каждые шесть недель. Rust 1.1 beta был доступен одновременно с выпуском Rust 1.0. +Первый выпуск Rust, 0.1, произошел в январе 2012 года. В течение 3 лет развитие продвигалось настолько быстро, что язык серьезно менялся без сохранения совместимости. Это дало возможность обкатать и отполировать синтаксис и возможности языка. -Хотя Rust является языком относительно низкого уровня, Rust имеет некоторые функциональные концепции, которые обычно -встречаются на языках более высокого уровня. Это делает Rust не только быстрым, но и простым и эффективным для ввода кода. +15 мая 2015 года был выпущен Rust 1.0 с полной гарантией обратной совместимости. Сборка поставляется в трех вариантах: стабильная версия, бета-версия, ночная версия. Все нововведения языка сперва обкатываются на ночной и бета-версиях, и только потом попадают в стабильную. Выход очередной версии происходит раз в 6 недель. В 2018 году вышло второе большое обновление языка, добавившее ему новых возможностей. + +Хотя Rust является языком относительно низкого уровня, он имеет все возможности высокоуровневых языков: процедурное, объектное, функциональное, шаблонное и другие виды программирования. На данный момент Rust является одним из самых мощных (а может быть и самым) по возможностям среди статически типизированных языков. Это делает Rust не только быстрым, но и простым и эффективным для разработки сложного кода. ```rust -// Это однострочный комментарии +// Это однострочный комментарий // /// Так выглядит комментарий для документации /// # Examples /// -/// +/// ``` /// let seven = 7 -/// +/// ``` /////////////// // 1. Основы // @@ -63,10 +60,9 @@ fn main() { let y: i32 = 13i32; let f: f64 = 1.3f64; - // Автоматическое выявление типа данных + // Автоматическое выведение типа данных // В большинстве случаев компилятор Rust может вычислить - // тип переменной, поэтому - // вам не нужно писать явные аннотации типа. + // тип переменной, поэтому вам не нужно явно указывать тип. let implicit_x = 1; let implicit_f = 1.3; @@ -87,12 +83,11 @@ fn main() { // Печать на консоль println!("{} {}", f, x); // 1.3 hello world - // `String` – изменяемя строка + // `String` – изменяемая строка let s: String = "hello world".to_string(); - // Строковый срез - неизменяемый вид в строки - // Это в основном неизменяемая пара указателей на строку - - // Это указатель на начало и конец строкового буфера + // Строковый срез - неизменяемое представление части строки + // Представляет собой пару из указателя на начало фрагмента и его длины let s_slice: &str = &s; @@ -130,7 +125,7 @@ fn main() { // 2. Типы // ////////////// - // Struct + // Структура struct Point { x: i32, y: i32, @@ -154,6 +149,8 @@ fn main() { let up = Direction::Up; // Перечисление с полями + // В отличие от C и C++ компилятор автоматически следит за тем, + // какой именно тип хранится в перечислении. enum OptionalI32 { AnI32(i32), Nothing, @@ -175,7 +172,7 @@ fn main() { // Методы // impl<T> Foo<T> { - fn get_bar(self) -> T { + fn get_bar(self) -> T { self.bar } } @@ -198,9 +195,9 @@ fn main() { let another_foo = Foo { bar: 1 }; println!("{:?}", another_foo.frobnicate()); // Some(1) - ///////////////////////// - // 3. Поиск по шаблону // - ///////////////////////// + ///////////////////////////////// + // 3. Сопоставление по шаблону // + ///////////////////////////////// let foo = OptionalI32::AnI32(1); match foo { @@ -223,9 +220,9 @@ fn main() { println!("The second number is Nothing!"), } - ///////////////////// + ////////////////////////////////////////////// // 4. Управление ходом выполнения программы // - ///////////////////// + ////////////////////////////////////////////// // `for` loops/iteration let array = [1, 2, 3]; @@ -233,7 +230,7 @@ fn main() { println!("{}", i); } - // Отрезки + // Диапазоны for i in 0u32..10 { print!("{} ", i); } @@ -266,12 +263,12 @@ fn main() { break; } - ///////////////////////////////// + ////////////////////////////////// // 5. Защита памяти и указатели // - ///////////////////////////////// + ////////////////////////////////// // Владеющий указатель – такой указатель может быть только один - // Это значит, что при вызоде из блока переменная автоматически становится недействительной. + // Это значит, что при выходе из блока переменная автоматически становится недействительной. let mut mine: Box<i32> = Box::new(3); *mine = 5; // dereference // Здесь, `now_its_mine` получает во владение `mine`. Т.е. `mine` была перемещена. diff --git a/ru-ru/sql-ru.html.markdown b/ru-ru/sql-ru.html.markdown new file mode 100644 index 00000000..7353a175 --- /dev/null +++ b/ru-ru/sql-ru.html.markdown @@ -0,0 +1,120 @@ +--- +language: SQL +filename: learnsql-ru.sql +contributors: + - ["Bob DuCharme", "http://bobdc.com/"] +translators: + - ["Shaltaev", "https://github.com/shaltaev"] + - ["Andre Polykanine", "https://github.com/Menelion"] +lang: ru-ru +--- + +Язык структурированных запросов (SQL) — это стандартный язык ISO для создания +и работы с базами данных, хранящимися в наборе таблиц. Реализации обычно +добавляют свои собственные расширения к языку; +[Сравнение различных реализаций SQL](http://troels.arvin.dk/db/rdbms/) — хороший справочник по различиям в продуктах. + +Реализации обычно предоставляют приглашение командной строки, где вы можете +вводить команды, описанные ниже, в интерактивном режиме, также есть способ +выполнить серию таких команд, сохранённых в файле скрипта. +(Результат того, что вы сделали с помощью интерактивного режима, является +хорошим примером того, что не стандартизировано, — большинство реализаций SQL +поддерживают ключевые слова QUIT, EXIT или оба). + +Некоторые команды ниже предполагают использование +[демонстрационного образца базы данных сотрудников от MySQL](https://dev.mysql.com/doc/employee/en/), доступного на [Github](https://github.com/datacharmer/test_db). +Следовательно, для повторения команд в локальном окружении он должен быть загружен. +Файлы на github — это скрипты с командами, которые схожи с командами ниже, +которые создают и манипулируют таблицами и данными о сотрудниках вымышленной +компании. Синтаксис для запуска этих скриптов будет зависеть от используемой +вами реализации SQL. Обычно используется утилита, запускаемая из командной +строки в вашей операционной системе. + +```sql +-- Комментарии начинаются с двух дефисов. Завершайте каждую команду +-- точкой с запятой. + +-- SQL не учитывает регистр букв для ключевых слов. Примеры команд здесь +-- следуют соглашению о написании в верхнем регистре, потому что +-- это позволяет легче отличить их от имён баз, таблиц и колонок. + +-- Создание и удаление базы данных. Имена базы и таблицы чувствительны +-- к регистру букв. +CREATE DATABASE someDatabase; +DROP DATABASE someDatabase; + +-- Список доступных баз. +SHOW DATABASES; + +-- Выбор базы для работы. +USE employees; + +-- Выбрать все строки и колонки из таблицы «departments» (отделы) текущей базы. +-- В интерактивном режиме обыч но результат будет выведен на экран. +SELECT * FROM departments; + +-- Тот же запрос, что и выше, но выбор только колонок «dept_no» и «dept_name». +-- Разбиение команд на несколько строк допустимо. +SELECT dept_no, + dept_name FROM departments; + +-- В данном случае будут выбраны все колонки, но только первые 5 строк. +SELECT * FROM departments LIMIT 5; + +-- Выбор названий отделов, содержащих подстроку «en». +SELECT dept_name FROM departments WHERE dept_name LIKE '%en%'; + +-- Выбор всех колонок, где названия отделов начинаются на «S», +-- после которой идёт ровно четыре символа. +SELECT * FROM departments WHERE dept_name LIKE 'S____'; + +-- Выбор всех должностей из таблицы «titles», но без повторений. +SELECT DISTINCT title FROM titles; + +-- В дополнение к предыдущему запросу результат будет отсортирован +-- в алфавитном порядке (с учётом регистра). +SELECT DISTINCT title FROM titles ORDER BY title; + +-- Показать число строк в таблице отделов. +SELECT COUNT(*) FROM departments; + +-- Показать число строк, где название отдела содержит подстроку «en» +SELECT COUNT(*) FROM departments WHERE dept_name LIKE '%en%'; + +-- Объединение информации из нескольких таблиц: +-- В таблице «titles» перечислены должности, кто их занимал по номеру сотрудника, +-- а также с какой даты по какую. Получим эту информацию, но используем номера +-- сотрудников как ссылку на таблицу «employees», чтобы получить имя и фамилию +-- каждого сотрудника. Выводим только 10 строк. +SELECT employees.first_name, employees.last_name, + titles.title, titles.from_date, titles.to_date +FROM titles INNER JOIN employees ON + employees.emp_no = titles.emp_no LIMIT 10; + +-- Список всех таблиц во всех базах. Реализации обычно предоставляют +-- собственные сокращения, чтобы показать все таблицы текущей базы. +SELECT * FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_TYPE='BASE TABLE'; + +-- Создать таблицу с именем tablename1 и двумя колонками в текущей базе. +-- Для колонок имеется множество параметров, таких как тип данных. +CREATE TABLE tablename1 (fname VARCHAR(20), lname VARCHAR(20)); + +-- Вставляем строку данных в таблицу «tablename1». Предполагаем, что таблица +-- настроена таким образом, чтобы принимать эти значения. +INSERT INTO tablename1 VALUES('Richard','Mutt'); + +-- В таблице «tablename1» изменить значение fname на «John» +-- для каждой строки, где колонка lname равна «Mutt». +UPDATE tablename1 SET fname='John' WHERE lname='Mutt'; + +-- Удалить из таблицы «tablename1» строки, +-- где значение колонки lname начинается с «M». +DELETE FROM tablename1 WHERE lname like 'M%'; + +-- Удалить все строки из таблицы «tablename1». В итоге получим пустую таблицу. +DELETE FROM tablename1; + +-- Удалить таблицу «tablename1» полностью. +DROP TABLE tablename1; +``` diff --git a/ru-ru/yaml-ru.html.markdown b/ru-ru/yaml-ru.html.markdown index 6eb580d9..ddaed2b6 100644 --- a/ru-ru/yaml-ru.html.markdown +++ b/ru-ru/yaml-ru.html.markdown @@ -2,7 +2,7 @@ language: yaml filename: learnyaml-ru.yaml contributors: -- [Adam Brenecki, 'https://github.com/adambrenecki'] +- [Leigh Brenecki, 'https://github.com/adambrenecki'] - [Suhas SG, 'https://github.com/jargnar'] translators: - [Sergei Babin, 'https://github.com/serzn1'] @@ -24,7 +24,7 @@ YAML как язык сериализации данных предназнач # Скалярные величины # ###################### -# Наш корневой объект (который продолжается для всего документа) будет соответствовать +# Наш корневой объект (который продолжается до конца документа) будет соответствовать # типу map, который в свою очередь соответствует словарю, хешу или объекту в других языках. key: value another_key: Другое значение ключа. |