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