Создание сайтов в Луганске, ЛНР. Введение в R и RStudio

С увеличением вычислительной мощности увеличивается доступ к большим объемам данных в свободном доступе. Люди отслеживают свою жизнь с помощью трекеров производительности, калорий, фитнеса и сна. Правительства публикуют данные опросов направо и налево, а компании проводят тестирование аудитории, которое необходимо проанализировать. Даже сейчас есть много данных, готовых к тому, чтобы их можно было взять и просмотреть.

В этом руководстве мы рассмотрим основы языка программирования R — языка, созданного исключительно для статистических вычислений. Я не буду утомлять вас определениями из Википедии. Вместо этого давайте погрузимся прямо в это. В этом введении мы рассмотрим установку IDE и языка по умолчанию, а также его типы данных.

Установка

R — это и язык программирования, и программная среда, что означает, что он полностью автономен. Есть два шага для его установки:

загрузите и установите последнюю версию R: www.r-project.org

загрузите и установите RStudio, R IDE: www.rstudio.com

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

После установки инструментов запустите R Studio.

RStudio IDE

Области IDE

Кратко объясним графический интерфейс. Есть четыре основные части. Я объясню порядок по умолчанию, но обратите внимание, что его можно изменить в Settings/Preferences > Pane Layout.

Редактор

Редактор

Верхний левый квадрант — это редактор. Здесь вы пишете код R, который хотите сохранить на потом — функции, классы, пакеты и т. д. Во всех смыслах и целях это идентично главному окну любого другого редактора кода. Помимо некоторых кнопок, которые говорят сами за себя, и других, которые не должны касаться вас в этой отправной точке, есть также флажок «Источник при сохранении». Это означает «загружать содержимое файла в среду выполнения моей консоли каждый раз, когда я сохраняю файл». Вы должны всегда иметь его включенным, так как это ускоряет процесс разработки одним щелчком мыши.

Консоль

Консоль

Нижний левый квадрант — это консоль. Это REPL для R, в котором вы можете проверить свои идеи, наборы данных, фильтры и функции. Здесь вы будете проводить большую часть своего времени в начале. Здесь вы проверяете, что ваша идея работает, прежде чем копировать ее в редактор выше. Это также среда, в которой ваши файлы R будут загружаться при сохранении (см. выше), поэтому всякий раз, когда вы разрабатываете новую функцию в файле R выше, она автоматически становится доступной в этом REPL. Мы проведем много времени в REPL в оставшейся части этого руководства.

История / Окружающая среда

Панель История/Среда

Верхний правый квадрант имеет две вкладки: Environment и History.

Окружение относится к среде консоли (см. выше) и будет подробно перечислять каждый отдельный символ, который вы определили в консоли (будь то через источник или напрямую). То есть, если у вас есть функция, доступная в REPL, она будет указана в среде. Если у вас есть переменная или набор данных, они будут перечислены там. Здесь вы также можете импортировать пользовательские наборы данных вручную и мгновенно сделать их доступными в консоли, если вам не хочется вводить для этого команды. Вы также можете проверить среду других пакетов, которые вы установили и загрузили. (Подробнее о пакетах позже.) Идите вперед и поэкспериментируйте с этим; ничего не сломаешь.

В истории перечислены все консольные команды, которые вы выполнили с момента запуска последнего проекта. Он сохраняется в скрытом.Rhistoryфайле в папке вашего проекта. Если вы не решите сохранить свою среду после сеанса, история не будет сохранена.

Разное

Панель «Разное»

Нижняя правая панель представляет собой панель «Разное» и содержит пять отдельных вкладок. Первый, Files, говорит сам за себя.

Вкладка «Графики «будет содержать графики, созданные вами с помощью R. Здесь вы можете масштабировать, экспортировать, настраивать и просматривать свои диаграммы и графики.

Вкладка «Пакеты «позволяет устанавливать дополнительные пакеты в R. Краткое описание находится рядом с каждым доступным пакетом, хотя их гораздо больше, чем перечислено там. Мы рассмотрим репозитории пакетов в следующем посте.

Вкладка «Справка «позволяет выполнять поиск в невероятно обширном каталоге справки и автоматически открывается всякий раз, когда вы вызываете справку по команде в консоли. (Справка вызывается путем добавления перед именем команды вопросительного знака, например:? data.frame.)

Наконец, Viewer — это, по сути, встроенный в RStudio браузер. Да, вы можете разрабатывать веб-приложения с помощью R и даже запускать в нем локально размещенные веб-приложения.

Встроенные наборы данных

В приведенном ниже тексте всякий раз, когда я упоминаю об использовании команды, предполагайте, что это означает ввод ее в консоль. Итак, если я говорю «Смотрим справку по DataFrames с помощью? data.frame», вы делаете так:

GIF-файл, показывающий запуск? data.frame в консоли

RStudio поставляется с некоторыми наборами данных, с которыми новые пользователи могут поиграть. Чтобы использовать встроенный набор данных, мы загружаем его dataфункцией и предоставляем аргумент, соответствующий набору, который нам нужен. Чтобы увидеть все доступные встроенные наборы, введите data (), без аргумента.

Наборы данных в RStudio

Глядя на список доступных наборов данных, давайте для начала загрузим очень маленький:

data ('women’)

Вы должны увидеть womenпеременную на панели Environment, хотя во втором поле указано . Обещание в этом случае просто означает: «Данные будут там, когда они вам действительно понадобятся». Мы сказали R загрузить этот набор, но на самом деле мы нигде его не использовали, поэтому он не чувствовал необходимости полностью загружать его в память. Давайте скажем R, что нам это нужно. В консоли распечатайте весь набор, просто вызвав это:

women

Это эквивалентно:

print (women)

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

Числа будут выведены в консоли, а запись Environment для womenдолжна измениться. Теперь вы также сможете увидеть данные на панели среды, щелкнув синюю стрелку расширения рядом с именем переменной.

Набор данных о женщинах, расширенный

В этом наборе всего 15 элементов, и поэтому он не предлагает ничего ценного, но он достаточно хорош для игры.

Для дальнейшего изучения набора, с которым вы имеете дело, следует помнить о нескольких функциях (демонстрацию каждой из них можно увидеть ниже пояснений):

nrow/ ncolбудет перечислять количество строк/столбцов соответственно.

summaryвыведет сводку о столбцах набора. В случае с womenнабором у нас есть два числовых столбца (оба столбца числовые, или, другими словами, каждый столбец является числовым вектором; подробнее о типах данных и векторах позже). И R знает, что когда вы запросите у него анализ числового вектора, он должен выдать вам типичные значения для таких коллекций: минимальное значение в наборе, среднее (среднее) между минимумом и средним, среднее (среднее всех значений), среднее между средним и максимальным, и максимальное, наибольшее число в столбце. Это делается как для высоты, так и для ширины. Для разных типов векторов (например, для тех, где каждый элемент представляет собой слово, а не число) вывод отличается.

strэто другой вид резюме. На самом деле strозначает «структура» и выводит сводную информацию о структуре набора данных. В нашем случае он сообщит нам, что это «data.frame» (особый тип данных, который мы объясним позже) с 15 наблюдениями (наблюдениями или строками) и двумя переменными (или столбцами). Затем он продолжает перечислять все столбцы в DataFrame с некоторыми (но не со всеми) их значениями, чтобы мы могли понять, с какими значениями мы имеем дело.

dimдает вам размеры набора данных. Вызов dim (women) дает нам 15 2, что означает 15 строк и два столбца. lengthможет использоваться для подсчета количества вертикальных элементов в наборе. В векторах (см. ниже) это количество элементов; в таких наборах данных, как womenэто количество столбцов:

> nrow (women)

[1] 15

> ncol (women)

[1] 2

> summary (women)

height weight

Min.:58.0 Min.:115.0

1st Qu.:61.5 1st Qu.:124.5

Median:65.0 Median:135.0

Mean:65.0 Mean:136.7

3rd Qu.:68.5 3rd Qu.:148.0

Max.:72.0 Max.:164.0

> str (women)

'data.frame’: 15 obs. of 2 variables:

$ height: num 58 59 60 61 62 63 64 65 66 67...

$ weight: num 115 117 120 123 126 129 132 135 139 142...

> dim (women)

[1] 15 2

Вы будете часто использовать эти функции, поэтому я рекомендую вам ознакомиться с ними. Загрузите некоторые другие наборы данных и проверьте их следующим образом. Нет необходимости знать их наизусть. Этот учебник и файлы справки всегда будут под рукой для справки, но в любом случае приятно свободно ими пользоваться.

Типы данных

В R есть несколько типичных атомарных типов данных, о которых вы уже знаете из других языков, но он также предоставляет несколько типов, ориентированных на статистику. Кратко пройдемся по ним. Объясняя эти типы, я расскажу об их назначении. Назначение в R выполняется с помощью оператора «стрелка влево» или ←, как в:

myString ← 'Hello, World!'

R, однако, очень снисходителен и позволит вам использовать = оператор присваивания в средах верхнего уровня, таких как консоль, если вам не хочется каждый раз набирать стрелку:

myString = 'Hello, World!'

Однако я предлагаю вам привыкнуть к стреле, так как без нее вы далеко не уйдете.

Для проверки типа (или класса) переменной classможно использовать функцию (правда strсверху делает почти то же самое): class (myString).

Атомикс

Атомарные классы являются базовыми типами, из которых строятся другие.

Характер

Класс character— это ваша обычная строка, набор из одной или нескольких букв:

> myString ← 'Hello, World!'

> class (myString)

[1] 'character’

Об [1]этом будет рассказано ниже, в разделе «Векторы».

Числовой

Класс numericсоответствует floatв других языках. Он указывает числовые значения, такие как 10, 15,6, -48792,5498982749879 и т. д.:

> myNum ← 5.983904798274987298

> class (myNum)

[1] 'numeric’

Вы можете преобразовать (изменить тип) числовые строковые значения в числовые типы, например:

> myString ← '5.60'

> class (myString)

[1] 'character’

> myNumber ← as.numeric (myString)

> myNumber

[1] 5.6

> class (myNumber)

[1] 'numeric’

Есть также специальное число Inf, которое представляет бесконечность. Его можно использовать в расчетах:

> 1/0

[1] Inf

Другое «число» — это NaN, что означает «не число». Это то, что вы получаете, когда делаете что-то вроде 0/0.

Целое число

Целые числа — это целые числа, хотя они автоматически преобразуются (изменяются) в числовые при сохранении в переменных:

> myInt ← 209173987

> class (myInt)

[1] 'numeric’

Чтобы на самом деле заставить их быть целыми числами, нам нужно вызвать функцию, которая приводит их вручную, называемую as.integer:

> myInt ← as.integer (myInt)

> class (myInt)

[1] 'integer’

Вы можете предотвратить автоприведение, установив целые числа с Lсуффиксом:

> myInt = 5L

> class (myInt)

[1] 'integer’

Обратите внимание, что если вы дадите R число, превышающее то, что может хранить его память, он автоматически преобразует его в действительное число, даже если вы поместите Lв конце:

> myInt ← 2479827498237498723498729384

> class (myInt)

[1] 'numeric’

> myInt

[1] 2.479827e+27

Но если вы затем попытаетесь привести это число к целому числу, R отбросит его, потому что он просто не может сделать целые числа такими большими. Вместо числа вы получаете «NA», особый тип в R, указывающий «Not Available», также известный как отсутствующее значение:

> myIntCoerced ← as.integer (myInt)

Warning message:

NAs introduced by coercion

> myIntCoerced

[1] NA

> class (myIntCoerced)

[1] 'integer’

NA по-прежнему является типом «целого числа», но без значения.

Обратите внимание, что при преобразовании числовых значений в целые числа десятичные разряды теряются. То же самое относится к преобразованию из числовых десятичных строк:

> myString ← '5.60'

> myNumeric ← 5.6

> myInteger1 ← as.integer (myString)

> myInteger2 ← as.integer (myNumeric)

> myInteger1 == myInteger2

[1] TRUE

> myInteger1

[1] 5

Сложный

Объяснение комплексных чисел немного выходит за рамки этого руководства, особенно если вы не знакомились с ними в школе, но если вам интересно, вы можете узнать больше о комплексных числах в Википедии. Они принимают форму a + biгде aи bдействительные числа и iмнимые. В R они создаются с помощью специальной complexфункции:

> myComplex ← complex (1, 3292, 8974892)

> myComplex

[1] 3292+8974892i

> class (myComplex)

[1] 'complex’

Они вам понадобятся не так часто, как другие типы, но если вы хотите узнать больше об этой complexфункции, просто обратитесь за помощью:? complex.

Логический

Логические типы (булевы значения) такие же, как и в большинстве других языков, и могут принимать два значения: либо истина, либо ложь. True может быть представлен с помощью TRUEили T, в то время как false предсказуемо FALSEили F:

> TRUE == T

[1] TRUE

> myBool ← TRUE

> myBool == T

[1] TRUE

> myComparison ← 5 > 6

> myComparison == FALSE

[1] TRUE

> class (myComparison)

[1] 'logical’

Всякий раз, когда вы создаете выражение, результатом которого является значение «да» или «нет», вы получаете TRUEили FALSE— как в случае 5 > 6выше. 5 не больше 6, поэтому выражение становится FALSE. Сравнение myComparisonс FALSEтаким образом дает TRUE, потому что myComparisonпеременная действительно содержит значение FALSE.

Когда это необходимо функции, логические значения будут преобразованы в числовые. Это означает, что если я напишу 1 + TRUE, консоль выдаст 2, тогда как 1 + FALSEвыдаст 1. Точно так же мы можем легко привести другие типы к логическим (as.logical (myVariable)). Любое числовое или целое число со значением, отличным от 0 или NA, даст TRUE. 0 и 0L даст FALSE. Такие строки, как «True», «TRUE», «true» и «T», будут преобразованы в TRUE, «False», «FALSE», «false» и «F» будут преобразованы в FALSE. Любая другая строка будет преобразована в логическое значение NA.

Высшие типы

Высшие типы — это типы, составленные из низших.

Векторы и списки

Самый важный из них — вектор — представляет собой набор элементов одного типа. В нашем предыдущем примере набора данных один столбец womenнабора данных был числовым вектором, то есть это была коллекция, содержащая только числовые значения. Вектор может содержать только элементы одного и того же типа. Векторы могут быть созданы с помощью vectorфункции, но обычно создаются с помощью сокращенной c (конкатенации) функции:

> myVector ← c ('Hello’, 'World’, 'Third Element’)

> class (myVector)

[1] 'character’

> myVector

[1] 'Hello’ 'World’ 'Third Element’

Здесь мы видим, что класс вектора является «символьным», что означает, что он содержит только значения символьного типа. Если мы распечатаем его, просто вызвав имя его переменной, мы получим все три элемента и файл [1]. Буквально это означает: «[1]Я вывожу содержимое вашего вектора. Первый элемент в этой строке — это элемент номер 1 в векторе».

То, что вы видите, []полностью зависит от размера вашей панели консоли и длины массива. Например:

> myVector ← c ('One’, 'Two’, 'Three’, 'Four’, 'Five’, 'Six’, 'Seven’, 'Eight’, 'Nine’, 'Ten’, 'Eleven’, 'Twelve’, 'Thirteen’, 'Fourteen’, 'Fifteen’)

> myVector

[1] 'One’ 'Two’ 'Three’ 'Four’ 'Five’ 'Six’ 'Seven’

[8] 'Eight’ 'Nine’ 'Ten’ 'Eleven’ 'Twelve’ 'Thirteen’ 'Fourteen’

[15] 'Fifteen’

Число в квадратных скобках просто означает «Элемент после меня является N-м в наборе». Это делается исключительно для того, чтобы сделать вывод более читабельным и не влияет на фактические данные.

Обратите внимание, что векторы строго одномерны. Вы не можете добавить другой вектор в качестве элемента внутри существующего вектора; их элементы сливаются в один:

> v1 ← c ('a’, 'b’, 'c’)

> v2 ← c ('d’, 'e’, 'f’)

> v3 ← c (v1, v2)

> v3

[1] 'a’ 'b’ 'c’ 'd’ 'e’ 'f’

Вы можете сгенерировать целые числовые векторы, указав диапазон:

> myRange ← c (1:10)

> myRange

[1] 1 2 3 4 5 6 7 8 9 10

Списки похожи на векторы, только у них нет ограничения на возможность хранить исключительно элементы одного и того же типа. Они создаются с помощью listфункции или с помощью cфункции, если один из добавляемых элементов является списком:

> myList ← list (5, 'Hello’, 'Worlds’, TRUE)

> class (myList)

[1] 'list’

> myList

[[1]]

[1] 5

[[2]]

[1] 'Hello’

[[3]]

[1] 'Worlds’

[[4]]

[1] TRUE

Как и в случае с векторами, применяется правило одномерности. Добавление списка в другой приведет к объединению их элементов.

Вывод [[N]]означает «Первый элемент этого списка — это вектор с одним элементом 5, второй элемент этого списка — это вектор с одним элементом Hello... и т. д.». Добавление [[N]]к переменной, которая содержит список, фактически возвращает элемент. Мы можем легко это проверить:

> class (myList[[1]])

[1] 'numeric’

> class (myList[[2]])

[1] 'character’

> class (myList[[3]])

[1] 'character’

> class (myList[[4]])

[1] 'logical’

Данные. Кадр

DataFrames — это, по сути, таблицы со строками и столбцами, очень похожие на электронные таблицы. Набор womenданных, который мы загрузили выше, был DataFrame. Вы можете получить доступ к отдельным столбцам DataFrames, используя $оператор переменной, за которым следует имя столбца:

> women$height

[1] 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

Результат возвращается в виде числового вектора. Проверьте его класс с помощью class (women$height).

Если имя столбца содержит пробелы, вы можете заключить его в кавычки (women$«Female Height»), но вы также можете получить доступ к столбцу по его числовой позиции в списке столбцов. Например, мы знаем, что heightэто первый столбец:

> head (women[1])

height

1 58

2 59

3 60

4 61

5 62

6 63

> head (women[[1]])

[1] 58 59 60 61 62 63

Функция headговорит R вернуть только первые шесть результатов. Это сделано для того, чтобы наша консоль оставалась красивой и свободной от прокрутки, что отлично подходит для краткого просмотра наборов данных без их полной распечатки. (Противоположного можно добиться с помощью tail, которая распечатывает последние шесть результатов.)

Здесь мы видим, что при доступе к столбцу с помощью single-square-bracket [1]мы получаем DataFrame, но с одним столбцом меньше. Однако если мы получим к нему доступ с помощью двойной квадратной скобки [[1]], мы получим числовой вектор высот. Данные, возвращаемые с помощью одиночной скобки, остаются того же типа, что и родительские данные, в то время как метод доступа с двойной скобкой нацеливается на определенные значения в этом столбце и возвращает их в их самой элементарной форме — числовом векторе.

Мы создаем DataFrames с data.frameфункцией:

> men ← data.frame (height = c (50:65), weight = c (150:165))

> head (men)

height weight

1 50 150

2 51 151

3 52 152

4 53 153

5 54 154

6 55 155

Здесь мы создали образец menнабора данных, мало чем отличающийся от предыдущего womenнабора.

Если мы хотим получить только имена столбцов, мы используем namesфункцию. Мы даже можем присвоить ему значение и, таким образом, изменить имена столбцов:

> names (men)

[1] 'height’ 'weight’

> names (men) ← c ('Male Height’, 'Male Weight’)

> head (men)

Male Height Male Weight

1 50 150

2 51 151

3 52 152

4 53 153

5 54 154

6 55 155

Матрица

Матрицы — это многомерные векторы. Они похожи на DataFrames, но могут содержать значения только одного типа. Они создаются с помощью matrixфункции и требуют количество строк и столбцов в качестве параметров, а также значения для размещения в этих слотах:

> m ← matrix (nrow = 4, ncol = 5, 1:20)

> m

[, 1] [, 2] [, 3] [, 4] [, 5]

[1, ] 1 5 9 13 17

[2, ] 2 6 10 14 18

[3, ] 3 7 11 15 19

[4, ] 4 8 12 16 20

Что произойдет, если количество предоставленных значений не соответствует количеству ячеек?

> m ← matrix (nrow = 4, ncol = 5, 1:25)

Warning message:

In matrix (nrow = 4, ncol = 5, 1:25):

data length [25] is not a sub-multiple or multiple of the number of rows [4]

> m

[, 1] [, 2] [, 3] [, 4] [, 5]

[1, ] 1 5 9 13 17

[2, ] 2 6 10 14 18

[3, ] 3 7 11 15 19

[4, ] 4 8 12 16 20

Получаем предупреждение, но матрица все равно создается, а все лишние значения просто отбрасываются. Если значений меньше, чем ячеек, предоставленные значения перерабатываются до тех пор, пока матрица не заполнится:

> m ← matrix (nrow = 4, ncol = 5, 1:16)

Warning message:

In matrix (nrow = 4, ncol = 5, 1:16):

data length [16] is not a sub-multiple or multiple of the number of columns [5]

> m

[, 1] [, 2] [, 3] [, 4] [, 5]

[1, ] 1 5 9 13 1

[2, ] 2 6 10 14 2

[3, ] 3 7 11 15 3

[4, ] 4 8 12 16 4

Подобно тому, как DataFrames имеют namesатрибут/функцию, матрицы имеют dim (размерность). Изменение этого свойства может изменить форму матрицы:

> m ← 1:15

> m

[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

> dim (m)

NULL

> dim (m) ← c (3,5)

> m

[, 1] [, 2] [, 3] [, 4] [, 5]

[1, ] 1 4 7 10 13

[2, ] 2 5 8 11 14

[3, ] 3 6 9 12 15

> dim (m)

[1] 3 5

> dim (m) ← c (5,3)

> m

[, 1] [, 2] [, 3]

[1, ] 1 6 11

[2, ] 2 7 12

[3, ] 3 8 13

[4, ] 4 9 14

[5, ] 5 10 15

> dim (m)

[1] 5 3

> dim (m) ← NULL

> m

[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Здесь мы создали числовой вектор из 15 последовательных чисел (в таких случаях мы можем опустить c). Атрибута dimдля него не существовало, о чем свидетельствует dimфункция, возвращающая NULL, поэтому мы изменили его, присвоив ему числовой вектор 3, 5. Это привело к перетасовке элементов, чтобы они соответствовали вновь построенной матрице. Затем мы снова изменили размеры, инвертировав количество столбцов и строк на 5, 3, что снова дало другую матрицу. Наконец, обнуление размеров привело к созданию числового вектора с самого начала.

Также можно комбинировать/расширять/изменять векторы, кадры данных и матрицы с помощью cbindи rbind:

> v ← 1:5

> x ← 6:10

> bound ← cbind (v, x)

> bound

v x

[1, ] 1 6

[2, ] 2 7

[3, ] 3 8

[4, ] 4 9

[5, ] 5 10

> bound ← rbind (v, x)

> bound

[, 1] [, 2] [, 3] [, 4] [, 5]

v 1 2 3 4 5

x 6 7 8 9 10

Факторы

Факторы — это векторы с метками. Это отличается от символьных векторов или даже от числовых, потому что они являются тем, что разработчики R называют «самоописанием», что позволяет функциям R автоматически понимать их больше, чем другие типы. Они построены с помощью factorфункции, которой нужно передать вектор в качестве аргумента:

> f ← factor (c ('Hello’, 'World’, 'Hello’, 'Annie’, 'Hello’, 'World’))

> f

[1] Hello World Hello Annie Hello World

Levels: Annie Hello World

> table (f)

f

Annie Hello World

1 3 2

Уровни перечисляют уникальные элементы фактора. Функция tableзахватывает фактор и строит таблицу, состоящую из различных уровней фактора и количества их вхождений в фактор.

Я лично еще не нашел применения факторам в своих проектах, но я изучаю их.

Вывод

В этом руководстве мы рассмотрели основные типы данных в R и основы использования RStudio. Теперь вы вооружены всеми знаниями, необходимыми для начала некоторых основных операций с данными. Помните, что все описанные выше функции полностью доступны для поиска в файлах справки с помощью? function, где «функция» — это имя функции.

При изучении языка программирования принято сначала учить типы данных, затем логические операторы и только потом управляющие структуры, прежде чем переходить к более сложным вещам, таким как функции и классы. Но в этом уроке я считаю, что мы заложили достаточную основу, чтобы прыгнуть прямо в огонь и учиться на собственном примере.

Делитесь нашими материалами с друзьями!

 

 

Заказать разработку сайта