diff --git a/.gitignore b/.gitignore index 5b6a065..94a8c85 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .Rhistory .RData .Ruserdata +__pycache__/ diff --git a/01-01-about.Rmd b/01-01-about.Rmd index d76277f..a202c09 100644 --- a/01-01-about.Rmd +++ b/01-01-about.Rmd @@ -16,7 +16,7 @@ Git автоматически отслеживает изменения во в ![](./img/notFinal.gif){width=400px style="border: 1px solid #ddd"} ::: -Важная особенность Git в том, что участники могут работать и создавать версии независимо друг от друга на своих компьютерах. Каждый может работать над своей задачей, не мешая другим, даже если все редактируют один и тот же файл. Git поможет объединить изменения в одну общую версию. +Важная особенность Git в том, что пользователи могут работать и создавать версии независимо друг от друга на своих компьютерах. Каждый может работать над своей задачей, не мешая другим, даже если все редактируют один и тот же файл. Git поможет объединить изменения в одну общую версию. ```{r, include=FALSE} # Особенность звучит так себе, но ветки это реально основная фича Git. diff --git a/01-02-install.Rmd b/01-02-install.Rmd index 9c4f972..520d7b4 100644 --- a/01-02-install.Rmd +++ b/01-02-install.Rmd @@ -3,14 +3,14 @@ ## Проверьте наличие Git {#terminal} В комплекте с дистрибутивом Git устанавливается программа для терминала. -Чтобы её запустить, откройте Rstudio и в верхнем меню выберите **Tools → Terminal → New Terminal**. +Чтобы открыть терминал в Positron, вызовите поиск команд комбинацией клавиш Ctrl + Shift + P, найдите и выберите **Terminal: Create New Terminal**. В появившемся окне терминала введите команду `git` и нажмите клавишу Enter. Если вы видите результат как на скриншоте ниже, то Git установлен. Иначе нужно его установить --- см. инструкцию для вашей операционной системы ниже. -После установки перезапустите RStudio и повторите проверку. +После установки перезапустите Positron и повторите проверку. -![](./img/git.png){width="100%"} +![](./img/SCR-20260826-ofub.png){width="100%"} ## Windows diff --git a/01-03-shell.Rmd b/01-03-shell.Rmd index 5bd75b6..20f71a7 100644 --- a/01-03-shell.Rmd +++ b/01-03-shell.Rmd @@ -4,13 +4,14 @@ Команды для терминала вы встретите в документации и в интернете, ими легко поделиться и использовать в скриптах. Кроме терминала есть много других способов и их даже можно использовать одновременно. -Графические интерфейсы --- все они имеют ограничения и реализуют только часть возможностей Git, но достаточны для решения большинства задач. Это может быть интерфейс, встроенный в другие программы (например [RStudio](https://docs.posit.co/ide/user/ide/guide/tools/version-control.html), [Pycharm](https://www.jetbrains.com/help/pycharm/using-git-integration.html), [VS Code](https://code.visualstudio.com/docs/sourcecontrol/overview)) или самостоятельная программа (например [GitHub Desktop](https://github.com/apps/desktop), [GitKraken](https://www.gitkraken.com) [и многие другие](https://git-scm.com/downloads/guis)); +Графические интерфейсы --- все они имеют ограничения и реализуют только часть возможностей Git, но достаточны для решения большинства задач. Это может быть интерфейс, встроенный в другие программы (например [Positron](https://positron.posit.co/git.html), [Pycharm](https://www.jetbrains.com/help/pycharm/using-git-integration.html), [VS Code](https://code.visualstudio.com/docs/sourcecontrol/overview), [RStudio](https://docs.posit.co/ide/user/ide/guide/tools/version-control.html)) или самостоятельная программа (например [GitHub Desktop](https://github.com/apps/desktop), [GitKraken](https://www.gitkraken.com) [и многие другие](https://git-scm.com/downloads/guis)); Веб-интерфейсы --- прямо на сайте GitHub можно редактировать отдельные файлы, а также выполнять некоторые команды. -В этом курсе мы будем работать с Git одновременно в интерфейсе RStudio и в терминале, как это делает большинство пользователей R каждый день, а также через GitHub. -Поэтому запомните, как запустить терминал в RStudio --- -в верхнем меню выберите **Tools → Terminal → New Terminal** ([см. скриншот в предыдущей главе](#terminal)). +В этом курсе мы будем работать с Git одновременно в интерфейсе Positron и в терминале, как это делает большинство пользователей каждый день, а также через GitHub. +К терминалу можно вернуться в любой момент, переключаясь между вкладками **(1) CONSOLE** и **(2) TERMINAL** на нижней панели Positron. + +![](./img/SCR-20260826-ofub-2.png){width="100%"} Перед началом работы необходимо сделать несколько настроек. Укажите свое имя и адрес электронной почты, чтобы Git верно записывал информацию об авторе изменений. diff --git a/02-01-init.Rmd b/02-01-init.Rmd index 436f077..97947b8 100644 --- a/02-01-init.Rmd +++ b/02-01-init.Rmd @@ -7,35 +7,19 @@ Git может отслеживать изменения в любой папк **Репозиторий** --- это скрытая подпапка `.git`, в которой хранятся версии проекта и информация об изменениях. Всё необходимое для работы Git содержится непосредственно в ней. -Самый простой способ создать репозиторий --- вместе с проектом RStudio. -В верхнем меню выберите [File → New Project]{.figtext}. -В появившемся окне выберите [New directory]{.figtext}, а затем [New Project]{.figtext}. -На последнем шаге в поле [Directory name]{.figtext} введите название папки для проекта: [penguins]{.figtext}. -Она будет создана на вашем компьютере по адресу, указанному в поле [Create project as subdirectory of]{.figtext}. -‼️ Не забудьте поставить галочку напротив опции [ Create a git repository]{.figtext}, иначе проект будет создан без Git репозитория. -После нажатия кнопки [Create Project]{.figtext} окно RStudio перезагрузится с открытым проектом. - - - - - - - - - - -
![](./img/02-01-01-new-project.png){width="320px"}![](./img/02-01-02-new-project.png){width="320px"}
![](./img/02-01-03-new-project.png){width="320px"}![](./img/02-01-04-new-project.png){width="320px"}
- -При следующем запуске RStudio откроет последний проект. -Если этого не произойдет, чтобы открыть проект в верхнем меню выберите [File → Open Project]{.figtext} или [File → Recent Projects]{.figtext}. - -Убедитесь в том, что проект загружен, для этого обратите внимание на следующие элементы интерфейса: -В правом верхнем углу указано название проекта [(A)]{.figref}. -На панели файлов (по умолчанию она в нижнем правом углу) открыта папка с файлами проекта [(B)]{.figref}. - -![](./img/02-01-05-window.png){width="680px"} - -Когда в RStudio открыт проект, R и Git ищут файлы в папке проекта --- это так называемая **рабочая папка или рабочая область**. +Мы продолжим проект из курса «Введение в автоматизацию обработки данных на R». Откройте его в Positron по [инструкции из курса](https://stepik.org/lesson/2482459/step/5?unit=2520221): нажмите [Open]{.figtext} на верхней панели, выберите Open Folder… и найдите нужную папку. + +Если проекта нет, создайте его, как показано [в курсе](https://stepik.org/lesson/2482459/step/2?unit=2520221). Затем создайте папку `data`, скачайте файл [`penguins.csv`](https://stepik.org/media/attachments/lesson/2482459/penguins.csv) и поместите его туда. + +Убедитесь, что папка открыта: в панели [(1) Explorer]{.figtext} должны быть видны файлы, в том числе папка `data`. +Откройте пункт [(2) Source Control]{.figtext} на панели слева и нажмите [Initialize Repository]{.figtext}. +Positron создаст репозиторий в папке проекта. На панели в разделе [Changes]{.figtext} появится список файлов. + +Если у вас нет кнопки [Initialize Repository]{.figtext}, [проверьте установку Git](#install). + +![](./img/SCR-20260826-rxxf.png){width=100%} + +Когда в Positron открыт проект, R и Git ищут файлы в ней --- это так называемая **рабочая папка или рабочая область**.
Подробнее про поиск и адреса файлов. На разных компьютерах, например у разных участников, проект может находиться в разных местах. @@ -43,10 +27,10 @@ Git может отслеживать изменения в любой папк а у пользователя `scruz` допустим `C:\Users\scruz\penguins`. -Если в скрипте использовать полный адрес файла, например: +Если в документе использовать полный адрес файла, например: ```r -read_csv("/Users/mjordan/penguins/data/sample.csv") +read.csv("/Users/mjordan/r-course/data/penguins.csv") ``` то он будет работать только у пользователя `mjordan`. @@ -54,19 +38,29 @@ read_csv("/Users/mjordan/penguins/data/sample.csv") Чтобы он работал у всех, нужно указывать адрес файла относительно рабочей папки. ```r -read_csv("data/sample.csv") +read.csv("data/penguins.csv") ```
-Рассмотрим созданные RStudio файлы: +Внутри папки проекта создана папка репозитория `.git`. Открывать или изменять её содержимое не нужно, поэтому она скрыта. Для работы с репозиторием используют панель [Source Control]{.figtext} и команды в терминале. -- `hello-git.Rproj` --- содержит настройки проекта -- `.gitignore` --- содержит список файлов, которые Git не будет отслеживать; о том, зачем это нужно и как настроить [смотри в отдельном разделе](#gitignore) -- `.git` --- репозиторий; это скрытая папка, чтобы ее увидеть, в меню на панели файлов выберите [More → Show Hidden Files]{.figtext} +
Как увидеть скрытую папку. +Positron не показывает некоторые служебные папки на панели Explorer. +Чтобы увидеть их, откройте терминал и выполните команду: -Если файл `.gitignore` отсутствует, значит, вы не отметили галочку [ Create a git repository]{.figtext} при создании проекта или не установили Git. -[Проверьте наличие Git](#install) и создайте проект заново. +```shell +ls -la +``` + +В Windows может потребоваться другая команда: + +```powershell +Get-ChildItem -Force +``` + +Появится список файлов проекта, в том числе папка `.git`. +
-Итак, у нас есть проект RStudio --- папка, в которой мы будем работать, и +Итак, у нас есть проект --- папка, в которой мы будем работать, и внутри нее Git репозиторий --- скрытая папка, в которой будут храниться версии проекта. Приступим к созданию первой версии. diff --git a/02-02-commit.Rmd b/02-02-commit.Rmd index 44a2a77..bddfbed 100644 --- a/02-02-commit.Rmd +++ b/02-02-commit.Rmd @@ -5,43 +5,26 @@ Git отслеживает изменения в файлах, находящи а при помощи версий --- или, в терминах Git, **коммитов (commit)**. Коммиты нужно создавать вручную, выбирая, какие файлы вы хотите зафиксировать, добавив в версию. -Откройте в RStudio панель с названием [Git]{.figtext} (по умолчанию она в верхнем правом углу). -В отличие от списка файлов, на ней выводятся только те файлы, которые были изменены по сравнению с последней версией (коммитом). -Так как мы еще не создали ни одной версии, то в списке выводятся оба файла, созданных с проектом: `.gitignore` и `penguins.Rproj` - - -![](./img/02-02-01-window.png){width=680px} - -
Нет панели Git? -Значит, вы не отметили галочку [Create a git repository]{.figtext} при создании проекта или не установили Git. -[Проверьте наличие Git](#install) и [создайте проект заново](#git-init). -
- -Чтобы создать коммит (версию), отметьте файлы галочкой в столбце [Staged]{.figtext}. -Галочка напротив файла означает, что он добавлен в **индекс (staging)** --- -промежуточную область для выбора файлов, которые будут зафиксированы. -Неотмеченные файлы останутся в рабочей папке, но в коммит не попадут. -Вы можете добавить их в следующую версию позже или отменить изменения. -Нажмите кнопку [Commit]{.figtext}. - -![](./img/02-02-02-staging.png){width=400px} - -В открывшемся окне можно подробнее посмотреть, что изменилось в файлах. -Просмотрите изменения и введите краткое описание в поле [Commit message]{.figtext}. -В нашем примере был создан проект, это и будет подходящим описанием. +Откройте в Positron панель [Source Control]{.figtext}. +В отличие от панели с файлами [Explorer]{.figtext}, на ней выводятся только те файлы, которые были изменены по сравнению с последней версией (коммитом). +Так как мы еще не создали ни одной версии, то в списке выводятся все файлы проекта. + +Чтобы создать коммит (версию), наведите на заголовок [Changes]{.figtext} и нажмите `+`. +После этого файлы окажутся в разделе [Staged Changes]{.figtext} --- **индексе (staging)**, +промежуточной области для выбора файлов, которые войдут в новую версию (коммит). +Можно добавлять файлы и по одному, нажимая `+` только напротив нужных. +Файлы, не добавленные в индекс, останутся в рабочей папке, но не войдут в коммит. +Вы можете добавить их в следующую версию позже или отменить изменения, нажав `↶`. + +Введите краткое описание в поле [Message]{.figtext}. +В нашем примере мы закончили курс R, это и будет подходящим описанием: `Добавил файлы курса по R`. Нажмите кнопку [Commit]{.figtext} под текстовым полем. -![](./img/02-02-03-commit.png){width=600px} - -В открывшемся окне не должно быть ошибок, но должно быть сообщение как на изображении ниже. - -![](./img/02-02-04-message.png){width=600px} +![](./img/SCR-20260827-dsdg.png){width=100%} -Закройте окно с сообщением и окно создания коммита, вернитесь к RStudio. -Обратите внимание, теперь панель [Git]{.figtext} со списком измененных файлов пуста --- +Обратите внимание, теперь панель [Source Control]{.figtext} со списком измененных файлов пуста --- это значит, что изменений по сравнению с последней версией, которую мы только что создали, нет. -![](./img/02-02-05-git-pane.png){width=400px} Теперь у нас есть версия проекта, к которой можно вернуться в любой момент и начать работу с этого места. diff --git a/02-03-practice.Rmd b/02-03-practice.Rmd index a30a426..7109834 100644 --- a/02-03-practice.Rmd +++ b/02-03-practice.Rmd @@ -24,85 +24,98 @@ ## Импорт данных -Загрузите файл с данными [penguins.csv](https://github.com/yoursdearboy/git-101/releases/download/penguins/penguins.csv) в папку проекта. -Если нужно открыть папку в файловом менеджере операционной системы, в меню на панели [Files]{.figtext} выберите [More → Show Folder in New Window]{.figtext}. -Вернитесь в RStudio и убедитесь, что файл `penguins.csv` появился на панели [Git]{.figtext}. -![](./img/02-03-01-show-folder.png){width=400px} +Создайте документ Quarto для анализа и сохраните его под названием `paper.qmd` в корне проекта. Вспомнить как это делается можно в [курсе](https://stepik.org/lesson/2482460/step/2?unit=2520222). +Замените содержимое документа кодом ниже и сохраните файл. -Создайте скрипт для анализа. В меню на панели [Files]{.figtext} выберите [New File → R Script]{.figtext} и введите название файла `penguins.R` +````{cat, engine.opts = list(lang = "markdown")} +--- +title: "Длина клюва пингвинов" +format: + html: + embed-resources: true +--- -![](./img/02-03-02-new-file.png){width=400px} +```{r} +data <- read.csv("data/penguins.csv") -Скопируйте следующий код для импорта данных и сохраните его в созданном файле. -Выделите обе строки и запустите, нажав кнопку [Run]{.figtext} в правом верхнем углу редактора RStudio. -Если импорт данных работает, в консоли появится вектор из чисел. - -```r -data <- read.csv("penguins.csv") -data$bill_length_mm +mean(data$bill_len) ``` +```` + +Выполните чанк. +Функция `mean()` вернёт `NA`, потому что в данных нет двух значений длины клюва. +Пока вы проходили предыдущий курс, мы поймали этих двух пингвинов и измерили их клювы. +Скачайте [обновлённые данные](https://raw.githubusercontent.com/yoursdearboy/git-101/positron/course-project/updates/penguins.csv) и замените ими файл `data/penguins.csv`. Снова выполните чанк и убедитесь, что средняя длина клюва равна `43.91802`. + +На панели [Source Control]{.figtext} появятся два изменения: новый документ `paper.qmd` и обновлённый файл `penguins.csv`. +Выберите его и проверьте, чем новая версия отличается от прежней: +строки из старого файла выделяются красным цветом, а из нового зеленым. -Убедитесь, что файл скрипта также появился на панели [Git]{.figtext}. -Добавьте оба файла в индекс, отметив галочкой в столбце [Staged]{.figtext}, и создайте коммит. -В окне коммита обязательно проверьте содержимое скрипта `penguins.R`, -так как часто пользователи забывают сохранить файл перед добавлением в индекс. +Добавьте в индекс и документ `paper.qmd`, и обновлённый файл `penguins.csv`: без данных результат анализа нельзя будет воспроизвести. +Выберите файл `paper.qmd` и проверьте содержимое: если он пустой, вы забыли сохранить файл, а Git работает только с сохраненными изменениями. +Создайте коммит с описанием «Импортировал данные пингвинов». -![](./img/02-03-03-git-pane.png){width=690px} +![](./img/SCR-20260827-rohb.png){width=100%} -После создания коммита список измененных файлов на панели [Git]{.figtext} должен быть пуст. +После создания коммита список изменённых файлов на панели [Source Control]{.figtext} снова должен быть пуст. ## Визуализация Анализ новых данных полезно начинать с исследования распределения. -Для этого присвоим данные с длиной клюва переменной `x` и построим несколько вариантов гистограммы с разной шириной столбца. -Сохраните приведённый ниже код в тот же файл, запустите и посмотрите графики. +Для этого присвоим данные с длиной клюва переменной и построим несколько вариантов гистограммы с разной шириной столбца. +Замените код чанка на приведённый ниже, запустите и посмотрите графики. -```r -data <- read.csv("penguins.csv") -x <- data$bill_length_mm +```{r, eval=FALSE} +data <- read.csv("data/penguins.csv") -hist(x, breaks = seq(40, 60, 4)) -hist(x, breaks = seq(40, 60, 2)) -hist(x, breaks = seq(40, 60, 1)) -``` +x <- data$bill_len -После сохранения файл `penguins.R` снова появился в списке изменений на панели [Git]{.figtext}. -Добавьте его в индекс и проверьте изменения в окне коммита. +hist(x, breaks = seq(30, 60, 3)) +hist(x, breaks = seq(30, 60, 2)) +hist(x, breaks = seq(30, 60, 1)) +``` -Вы уже могли заметить, что новые строки выделяются зеленым цветом. -Красным цветом выделяются удаленные строки, а неизмененные остаются белыми. +Сохраните файл `paper.qmd` и он опять появится в списке изменений на панели [Source Control]{.figtext}. +Выберите его и проверье изменения: красным - старые строки, зеленым — новые. Такой формат записи изменений называется **«дифф» (diff)**. -Обратите внимание, что по умолчанию Git анализирует строки, а не отдельные слова или символы. -Поэтому получился следующий дифф: старая вторая строка была удалена, новая вторая строка добавлена (см. номера строк слева), хотя мы всего лишь добавили присвоение `x <- ` в начало строки. -![](./img/02-03-04-git-pane.png){width=690px} +Обратите внимание, что по умолчанию Git сравнивает строки, а не отдельные слова или символы. +Несмотря на то, что мы заменили `mean()` на присвоение `x <- ` в 11-й строке, Git показывает прежнюю строку как удалённую, а новую — как добавленную. Номера слева указывают положение этих строк в старой и новой версиях файла. -Убедитесь, что сделанные изменения соответствуют диффу на скриншоте выше, и создайте новый коммит с описанием «Добавили гистограммы для длины клюва». +![](./img/SCR-20260828-cufv.png){width=100%} + +Добавьте `paper.qmd` в индекс, введите описание «Добавил гистограммы для длины клюва» и нажмите [Commit]{.figtext}. +После создания коммита список изменённых файлов снова должен быть пуст. ## Экспорт Гистограмма с шириной столбца 2 выглядит наиболее информативно. -Такой график можно и опубликовать. -Чтобы экспортировать изображение, сохраните следующий код в файл скрипта и запустите его. +Соберём HTML-отчёт, чтобы поделиться с коллегами. + +Оставьте в коде чанка только один вариант гистограммы и сохраните файл. -```r -data <- read.csv("penguins.csv") -x <- data$bill_length_mm +```{r, eval=FALSE} +data <- read.csv("data/penguins.csv") -png("penguins-hist.png") -hist(x, breaks = seq(40, 60, 2)) -dev.off() +x <- data$bill_len + +hist(x, breaks = seq(30, 60, 2)) ``` -После этого в списке изменений на панели [Git]{.figtext}, кроме файла `penguins.R`, появился файл с изображением `penguins-hist.png`. +Нажмите [Preview]{.figtext} вверху окна редактора. +В корне проекта появится файл `paper.html`. Его мы тоже добавим в коммит. -Во-первых, так другие участники, загрузив проект, сразу увидят результат без необходимости запускать скрипт. +Во-первых, так другие участники, загрузив проект, сразу увидят результат без необходимости выполнять код. Во-вторых, если вы измените ширину столбца или другие настройки графика, будет удобно сравнить старую и новую версии. -Добавьте оба файла в индекс, проверьте изменения, изучив дифф, и создайте коммит с описанием «Сохранили гистограмму длины клюва». +![](./img/SCR-20260828-cvcb.png){width=100%} + +Добавьте оба файла в индекс и создайте коммит с описанием «Собрал отчёт о длине клюва». +Проверьте, что на панели [Source Control]{.figtext} не осталось «незакомиченных» изменений. -На этом остановимся и посмотрим историю версий в журнале Git. +На этом остановимся и далее посмотрим историю версий в журнале Git. +А пока несколько советов. ::: {.callout .callout-info} Делайте коммиты часто и не придавайте слишком большое значение планированию. diff --git a/02-04-log-n-diff.Rmd b/02-04-log-n-diff.Rmd index bb88292..5ac5dd9 100644 --- a/02-04-log-n-diff.Rmd +++ b/02-04-log-n-diff.Rmd @@ -5,23 +5,20 @@ Журнал позволяет изучить изменения от других участников или вспомнить свои собственные, и зачем они сделаны. Поэтому так важно писать ясные и содержательные описания коммитов. Используя журнал, можно найти, когда сделаны изменения, приведшие к ошибке, и вернуть проект к предыдущему состоянию. -В конце концов, его можно использовать для отчетности и бизнесс-аналитики по проекту. +В конце концов, его можно использовать для отчетности и бизнес-аналитики по проекту. -Чтобы открыть журнал, нажмите кнопку [History]{.figtext} на панели [Git]{.figtext}. +Чтобы открыть журнал, на панели [Source Control]{.figtext} разверните раздел [Graph]{.figtext} внизу. В открывшемся окне выводится список коммитов в обратном порядке --- последние коммиты находятся вверху. -В списке выводится краткая информация о коммите, а под списком подробная информация по выделенному коммиту. -![](./img/02-04-02-history.png){width=690px} +При наведении на коммит появляется краткая информация: имя автора, которое [мы указали в настройках](#setup), дата и описание, и самое важное — хэш коммита, его уникальный идентификатор. В примере это `967f8ad`, у вас он будет другим. -- SHA --- так называемый хэш коммита, который является его уникальным идентификатором в репозитории -- Author --- автор коммита \, [которые были указаны в настройках](#setup) -- Date --- дата и время создания коммита -- Subject --- описание коммита -- Parent --- хэш (идентификатор) предыдущего коммита +Кликните на коммит, чтобы посмотреть список изменений. Выберите файл, чтобы открыть дифф --- изменения, сделанные в этом коммите по сравнению с предыдущей версией. -Еще ниже показан дифф --- изменения, сделанные в этом коммите по сравнению с предыдущим. -Для больших файлов выводятся только те строки, которые поменялись, а также несколько строк выше и ниже, чтобы был понятен контекст. -Если нажать кнопку [View file]{.figtext} справа от названия файла, можно увидеть его полное содержимое, каким оно было зафиксировано создания коммита. +![](./img/SCR-20260828-dmxx.png){width=100%} + +Если нужна история только одного файла, выберите его на панели [Explorer]{.figtext} и откройте раздел [Timeline]{.figtext} внизу той же панели. +Выберите коммит, чтобы посмотреть изменения. +В разделе [Timeline]{.figtext} также есть автоматические контрольные точки, которые создаются при сохранении файла. Они не входят в Git-репозиторий и исчезнут через некоторое время. Даже если вы работаете в одиночку, полезно иметь под рукой историю изменений. Но по настоящему эта функция полезна, diff --git a/03-01-branches.Rmd b/03-01-branches.Rmd index 6ac3805..8654fcf 100644 --- a/03-01-branches.Rmd +++ b/03-01-branches.Rmd @@ -19,60 +19,50 @@ Git позволяет эффективно объединять эти изме Для этого используются так называемые ветки (branch). Почему ветки? Потому что начиная с выбранного коммита история изменений разветвляется. + +::: {style="float: left; clear: both; width: 200px; margin-right: 20px;"} +![](./img/SCR-20260828-dmxz.png){width=100%} +::: + По умолчанию, мы работаем в ветке `main` (ранее ветка по умолчанию называлась `master`, будьте готовы встретить и такое название). Ее можно сравнить со стволом дерева --- вот он слева на изображении. -В нашем проекте с пингвинами в ветке `main` 4 коммита, последний из которых содержит гистограмму для публикации. - -![](./img/03-01-00-history.png){width=600px} +В нашем проекте с пингвинами в ветке `main` 4 коммита и от любого из них можно начать новую ветку. Представим ситуацию --- из журнала приходит ответ Рецензента 2, в котором он просит заменить гистограмму на ящик с усами. С одной стороны, можно податься в журнал, где знают, что такое гистограмма, с другой, можно хотя бы попробовать удовлетворить пожелания рецензента и, -если нам не понравится новая диаграмма, просто удалить изменения. +если нам не понравится новая диаграмма, просто удалить ветку с изменениями. # Создание ветки {#git-branch} Чтобы спокойно поэкспериментировать создадим новую ветку. Так будет проще удалить изменения и они не будут мешать, если мы захотим поправить что-то действительно важное в основной ветке `main`. -В RStudio нажмите кнопку [New Branch]{.figtext} [(A)]{.figref} - -![](./img/03-01-01-new-branch.png){width=400px} - -В появившемся окне введите название, например `boxplot` и нажмите кнопку [Create]{.figtext}. -Откроется окно с сообщением, что мы переключились на ветку `boxplot`, -можете закрыть его кнопкой [Close]{.figtext}. +В Positron нажмите название текущей ветки `main` в строке состояния внизу окна и выберите [Create new branch…]{.figtext}. +В появившемся поле введите название, например `boxplot`, и нажмите Enter. +Positron переключится на новую ветку `boxplot`. +Обратите внимание, что название ветки в строке состояния поменялось с `main` на `boxplot`. -![](./img/03-01-02-new-branch.png){width=200px} - -![](./img/03-01-03-new-branch.png){width=400px} - -Обратите внимание, что название ветки на панели [Git]{.figtext}, рядом с кнопкой создания ветки [(A)]{.figref}, поменялось с `main` на `boxplot`. +![](./img/SCR-20260829-ckqm.png){width=100%} Вернемся к пингвинам. -Замените содержимое скрипта `penguins.R` на следующее: +Замените вызов `hist()` в чанке на вызов `boxplot()`: -```r -data <- read.csv("penguins.csv") -x <- data$bill_length_mm +```{r, eval=FALSE} +data <- read.csv("data/penguins.csv") + +x <- data$bill_len -png("penguins-boxplot.png") boxplot(x) -dev.off() ``` -Сохраните файл и выполните скрипт. -Обратите внмание, что мы поменяли название файла. -Старый файл `penguins-hist.png` в этой версии нам не нужен и его необходимо удалить. -Не переживайте, благодаря Git, в основной ветке `main` он останется. -На панели [Files]{.figtext} отметьте галочкой файл `penguins-hist.png` [(A)]{.figref} и нажмите кнопку [Delete]{.figtext} [(B)]{.figref}. - -![](./img/03-01-04-delete-files.png){width=400px} +Сохраните файл и нажмите [Preview]{.figtext}, чтобы обновить отчёт `paper.html`. +Не переживайте, благодаря Git в основной ветке `main` останется прежний вариант с гистограммой. -Отметьте все изменения для фиксации и создайте коммит. -Обратите внимание, что удаление файла это тоже изменение, которое надо отметить. +Отметьте все изменения для фиксации и создайте коммит с описанием «Заменил гистограмму на ящик с усами». +Обратите внимание, что в коммит должны попасть и исходный документ `paper.qmd`, и обновлённый отчёт `paper.html`. -![](./img/03-01-05-commit.png){width=400px} +![](./img/SCR-20260829-cltf.png){width=100%} Теперь отложим эксперименты и вернемся к прежней версии. diff --git a/03-02-checkout.Rmd b/03-02-checkout.Rmd index 9bfc862..934b80c 100644 --- a/03-02-checkout.Rmd +++ b/03-02-checkout.Rmd @@ -1,35 +1,40 @@ # Переключение веток {#git-checkout} -Для переключения ветки нажмите на название текущей ветки [(A)]{.figref} на панели [Git]{.figtext}. +Для переключения ветки нажмите на название текущей ветки в строке состояния Positron. В выпадающем списке выберите ветку на которую хотите переключиться (`main`). -![](./img/03-02-01-branch.png){width=400px} +![](./img/SCR-20260829-cqic.png){width=100%} -Убедитесь, что код скрипта вернулся к прежнему состоянию и строит гистограмму, -а в списке файлов находится файл с гистограммой `penguins-hist.png` и нету файла `penguins-boxplot.png`. - -![](./img/03-02-02-files.png){width=400px} +Убедитесь, что код документа `paper.qmd` вернулся к прежнему состоянию и вызывает функцию `hist()`, +а отчёт в окне просмотра строит гистограмму вместо ящика с усами. Это было просто. Но есть один случай, когда Git откажется переключать ветку --- если это приведет к потере данных. -Например, замените содержимое скрипта `penguins.R` на следующее (добавилась подпись оси X): +Например, замените код чанка на следующий (добавилась подпись оси X): + +```{r, eval=FALSE} +data <- read.csv("data/penguins.csv") -```r -data <- read.csv("penguins.csv") -x <- data$bill_length_mm +x <- data$bill_len -png("penguins-hist.png") -hist(x, breaks = seq(40, 60, 2), xlab = "Bill length, mm") -dev.off() +hist(x, breaks = seq(30, 60, 2), xlab = "Bill length, mm") ``` +::: {style="float: left; clear: both; width: 200px; margin-right: 20px;"} +![](./img/SCR-20260829-dlcs.png){width=100%} +::: + Сохраните файл и попробуйте переключиться на ветку `boxplot`. -Вы получите сообщение как на скриншоте ниже. -Если бы Git переключил ветку, ему бы пришлось перезаписать файл `penguins.R`, в который мы внесли изменения, но не зафиксировали. -Поэтому, чтобы не потерять изменения при переключении, сначала необходимо их зафиксировать создав коммит. +Вы увидите сообщение, как на скриншоте слева. +Если бы Git переключил ветку, ему бы пришлось перезаписать файл `paper.qmd`, в который мы внесли изменения, но не зафиксировали. +Positron предлагает временно спрятать изменения (**Stash**), чтобы можно было переключиться. +Но есть решение лучше — зафиксировать их создав коммит. +Нажмите **Cancel**, чтобы отменить переключение. +Добавьте изменения в индекс и создайте коммит с описанием «Добавил подпись оси». -![](./img/03-02-03-error.png){width=690px} +![](./img/SCR-20260829-damx.png){width=100%} -Создайте коммит и попробуйте переключиться на ветку `boxplot` и обратно на ветку `main`. +Попробуйте снова переключиться на ветку `boxplot`. +На этот раз переключение должно пройти без ошибок (убедитесь, что код в редакторе изменился). diff --git a/03-03-merge.Rmd b/03-03-merge.Rmd index ae3cbd4..ab137d5 100644 --- a/03-03-merge.Rmd +++ b/03-03-merge.Rmd @@ -1,23 +1,21 @@ # Слияние веток {#git-merge} -[Откройте окно истории](#git-log) и выберите в фильтре сверху показывать все ветки [(all branches)]{.figtext} и все коммиты [(all commits)]{.figtext}. -На диграмме наглядно видно почему это называется веткой. +На панели [Source Control]{.figtext} разверните раздел [Graph]{.figtext} внизу, как показано в главе +[просмотр истории](#git-log). +Справа от заголовка [Graph]{.figtext} нажмите [Auto]{.figtext} с иконкой ветки +и в выпадающем меню выберите [All]{.figtext}. +Диаграмма покажет обе ветки, и теперь должно быть ясно, почему они так называются. -![](./img/03-03-01-log.png){width=690px} +![](./img/SCR-20260829-dtuv.png){width=100%} -Если мы или другой участник проекта, решим принять эти изменения в основную ветку `main`, -нам нужно выполнить операцию «слияния» (merge). -В RStudio нет встроенной возможности слияния веток, это необходимо делать в терминале. -К счастью, команда совсем не сложная. +Если мы или другой участник проекта решим принять эти изменения в основную ветку `main`, +нам нужно выполнить операцию **«слияния» (merge)**. Для начала переключитесь на ветку, в которую будут вливаться изменения --- в нашем случае это `main` ([см. переключение веток](#git-checkout)). -Откройте терминал ^[В меню RStudio выберите Tools → Terminal → New Terminal] и введите команду для слияния с веткой `boxplot`. +На панели [Source Control]{.figtext} нажмите кнопку с троеточием справа от заголовка [Changes]{.figtext}. Выберите [Branch → Merge…]{.figtext}, а затем --- ветку `boxplot`. -```sh -git merge boxplot - -``` +![](./img/SCR-20260829-dzjy.png){width=100%} Git попытается автоматически объединить изменения из обеих веток и создать новый коммит. В большинстве случаев этого достаточно, @@ -27,69 +25,60 @@ Git попытается автоматически объединить изм Git предпочтет выдать ошибку и попросит вас разрешить конфликт. В списке изменений мы видим, -что Git автоматически выбрал изменения связанные с новым и старым файлом для графика -`penguins-hist.png` и `penguins-boxplot.png`, -но лишь частично для скрипта `penguins.R`. +что Git автоматически добавил в индекс отчёт `paper.html` из ветки `boxplot`, +но не документ `paper.qmd`, который отмечен восклицательным знаком. -![](./img/03-03-02-git-pane.png){width=400px} +Причина в том, что после изменения кода графика в ветке `boxplot` +мы изменили ту же строку в ветке `main`. +Откройте файл `paper.qmd`. +Git сохранил в нём обе версии кода и разделил их специальными маркерами: -Причина в том, что мы вносили изменения в код графика в ветке `main` после того как изменили его в ветке `boxplot`. -Откройте файл `penguins.R`. -Git любезно оставил для нас обе версии кода разделив специальными символами. -После строки `<<< HEAD` идет версия из текущей ветки, -строка `===` отделяет две версии друг от друга, -а строка `>>> boxplot` завершает версию из ветки `boxplot`. +- после строки `<<<<<<< HEAD` идёт версия из текущей ветки `main`, выделенная зелёным; +- строка `=======` отделяет две версии друг от друга; +- строка `>>>>>>> boxplot` завершает версию из ветки `boxplot`, выделенную синим. -![](./img/03-03-03-merge-conflict.png){width=690px} +![](./img/SCR-20260829-dzmv.png){width=100%} -Наша задача переписать выделенный участок (строки 4-12) в одну версию и убрать спецсимволы. -Важно понимать, что Git просто вставил в скрипт кусок текста, -но это все еще обычный R скрипт и мы должны привести его в рабочее состояние. +Нам нужно объединить изменения в одну версию и удалить маркеры. +Важно понимать, что это не часть интерфейса Positron, а обычный текст, который Git вставил прямо в файл. +Поэтому вместо одной строки у нас теперь пять (строки 13-17) и это не валидный синтаксис R: +попробуйте нажать **Preview** или выполнить чанк и убедитесь в этом. -Нам нужна версия из ветки `boxplot`, но мы хотим добавить в нее подпись оси, как это было сделано в ветке `main`. -Для этого оставим нижнюю версию (строки 9-11) и удалим лишние строки (4-8 и 12) -и добавим подпись, только для ящика с усами это должна быть подпись оси Y. -В итоге должен получиться следующий код. +Приведем документ в рабочее состояние: +за основу возьмём версию из ветки `boxplot`, но добавим в неё подпись оси из ветки `main`. +Удалите строки 13-15 со старой версией и разделяющими маркерами. +Добавьте подпись оси в вызов `boxplot()`. +У ящика с усами длина клюва показана по оси Y, поэтому для подписи используем аргумент `ylab`. +Также удалите строку 17 с маркером `>>>>>>>`. +В итоге должен получиться такой код. -```r -data <- read.csv("penguins.csv") -x <- data$bill_length_mm +```{r, eval=FALSE} +data <- read.csv("data/penguins.csv") + +x <- data$bill_len -png("penguins-boxplot.png") boxplot(x, ylab = "Bill length, mm") -dev.off() ``` -Сохраните файл и выполните скрипт. -Создайте коммит и -не забудьте отметить галочкой внесенные изменения, -в том числе обновившийся файл `penguins-boxplot.png`, который теперь содержит подпись оси. -Обычно сообщение коммита о слиянии веток содержит следующий текст «Merge branch название-ветки», но можете придумать свое. +Сохраните файл и нажмите [Preview]{.figtext}, чтобы обновить отчёт. +Добавьте в индекс изменённые файлы `paper.qmd` и `paper.html`. +Отчёт обновился, потому что по сравнению с версией из ветки `boxplot` в нём появилась подпись оси. +Создайте коммит. +Описание слияния обычно выглядит так: «Merge branch название-ветки», +но можете написать своё. -![](./img/03-03-04-git-pane.png){width=400px} +![](./img/SCR-20260829-nppw.png){width=100%} Итак, мы успешно слили изменения из ветки `boxplot` в основную ветку `main`. Теперь можно продолжить работу в основной ветке. Еще лучше будет создать очередную ветку для новых изменений, выполнить работу в ней и точно так же слить в основную. -![](./img/03-03-05-log.png){width=690px} - -
Как удалить ветку? Слитую ветку можно удалить. -В RStudio для этого нет встроенных средств, поэтому придется использовать терминал. -Выполните команду: +На панели [Source Control]{.figtext} нажмите кнопку с троеточием справа от заголовка [Changes]{.figtext}. +Выберите [Branch → Delete Branch…]{.figtext}, а затем ветку `boxplot`. -```sh -git branch -d boxplot -``` - -Если ветка не была слита, Git откажется ее удалять, ведь могут быть потеряны сделанные в ней изменения. -Если вы действительно уверены, что они вам не нужны и вы хотите удалить не слитую ветку, выполните команду: - -```sh -git branch -D boxplot -``` -
+Если ветка не была слита, Git предупредит, что при удалении можно потерять сделанные в ней изменения. +Удаляйте такую ветку только в том случае, если уверены, что изменения больше не нужны. ```{r, include=FALSE} # Советуем немного попрактиковаться и создать пару веток, diff --git a/04-01-github.Rmd b/04-01-github.Rmd index 928b329..20f3502 100644 --- a/04-01-github.Rmd +++ b/04-01-github.Rmd @@ -6,34 +6,10 @@ GitHub --- это веб-сервис для хранения Git репозит Ваши файлы размещаются на удаленном сервере и доступны публично или приватно для загрузки другими пользователями. В некотором смысле это аналог Dropbox или Google Drive для Git. Помимо хранения репозиториев, GitHub предоставляет другие инструменты: отслеживание задач, обсуждение изменений, запуск тестов и сборок и многое другое. -Для работы с GitHub вам понадобится зарегистрировать учетную запись и создать токен --- отдельный пароль для Git на вашем компьютере. - -## Регистрация на GitHub - -Перейдите на сайт github.com и зарегистрируйте учетную запись нажав на кнопку [Sign up]{.figtext} в верхнем правом углу или войдите в существующую учетную запись нажав [Sign in]{.figtext}. +Для работы с GitHub нужна учётная запись. Откройте github.com. +Если учётной записи нет, нажмите [Sign up]{.figtext} в правом верхнем углу и зарегистрируйтесь. Если она уже есть, нажмите [Sign in]{.figtext} и войдите. E-mail при регистрации не обязательно должен совпадать с указанным при настройке Git в [Главе 1](#setup). Дополнительные e-mail адреса можно добавить после регистрации [на странице настроек](https://github.com/settings/emails). Это рекоммендуется сделать, чтобы GitHub мог ассоциировать сделанные на компьютере коммиты с вашей учетной записью онлайн. -## Создание токена - -В целях безопасности, GitHub не позволяет использовать пароль от веб-сайта при работе с Git, -а требует создать так называемый **Personal Access Token** --- отдельный пароль специально для Git на вашем компьютере. -[Во всех случаях, когда Git запрашивает пароль от GitHub, необходимо вводить токен, а не пароль от веб-сайта.]{} - -Для этого перейдите по ссылке github.com/settings/tokens, -авторизуйтесь и нажмите **Generate new token**, в выпадающем списке выберите **classic**. -На новой странице введите название токена, например Work. -Отметьте следующие права `repo`, `workflow`, `user` -и нажмите зеленую кнопку **Generate token** в конце страницы. - -![](img/github-1.png){width=100%} -![](img/github-2.png){width=100%} - -Не забудьте скопировать и сохранить ваш токен - он выглядит как строка вида `ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`. -После того как вы закроете страницу посмотреть созданный токен невозможно. -Храните его в надежном месте как пароль. - -![](img/github-3.png){width=100%} - Теперь мы готовы опубликовать наш репозиторий на GitHub. diff --git a/04-02-remote.Rmd b/04-02-remote.Rmd index bb49e2b..cc231e5 100644 --- a/04-02-remote.Rmd +++ b/04-02-remote.Rmd @@ -1,4 +1,4 @@ -# Удаленный репозиторий {#git-remote} +# Удалённый репозиторий {#git-remote} ```{r, include=FALSE} # Рассказать про видимость репозиториев @@ -9,40 +9,51 @@ ![](./img/04-02-01-new-repository.png){width=400px} -В открывшейся форме достаточно заполнить только название репозитория в поле **Repository name**, например `penguins`. +В открывшейся форме достаточно заполнить только название репозитория в поле **Repository name**, например `r-course`. Остальные поля оставьте по умолчанию, мы только разберем за что они отвечают. -- Description --- краткое описание -- Public / Private --- настройка доступа +- **Description** --- краткое описание +- **Choose visibility** --- настройка доступа - Public --- кто угодно сможет просматривать ваши файлы, но только отдельно добавленные пользователи смогут их изменять - Private --- только отдельно добавленные пользователи смогут просматривать и изменять файлы -- Initialize this repository with --- этот раздел позволяет добавить в создаваемый репозиторий несколько типовых файлов `README` `.gitignore` и `LICENSE`; не отмечайте ни один из них, потому что в нашем репозитории на компьютере уже есть файлы и они будут конфликтовать с этими. +- **Add README**, **.gitignore**, **license** добавляет в создаваемый репозиторий шаблоны этих файлов; не отмечайте ни один, потому что в нашем репозитории на компьютере уже есть файлы и они будут конфликтовать с этими. Внизу страницы нажмите [Create repository]{.figtext}.
Пример заполненной формы -![](./img/04-02-02-new-repository.png){width=600px} +![](./img/SCR-20260829-obrj.png){width=600px}
-*Удалить это? Там и так на форме все написано, только что на англ. Оставить только предупреждение, чтобы не жали Initialize this repository with.* +```{r, include=FALSE} +# Удалить это? Там и так на форме все написано, только что на англ. Оставить только предупреждение, чтобы не жали Initialize this repository with. + +# Со скрином формы репозитория тоже ту мач? +``` + +Для созданного репозитория GitHub сгенерировал набор команд для быстрой настройки, воспользуемся ими. +Сначала необходимо убедиться, что напротив адреса репозитория выбрана опция доступа через [HTTPS]{.figtext} [(1)]{.figref}. -*Со скрином формы репозитория тоже ту мач?* +![](./img/SCR-20260830-cmvs.png){width=100%} -Для созданного репозитория GitHub сгенерировал набор команд быстрой настройки, воспользуемся ими. -Сначала необходимо убедиться, что напротив адреса репозитория выбрана опция доступа через [HTTPS]{.figtext} [(A)]{.figref}. -Далее скопируйте все три команды из раздела для существующего репозитория (**... or push an existing repository from the command line**, [B]{.figref}) и выполните в терминале ^[В меню RStudio выберите Tools → Terminal → New Terminal]. -На запрос пароля скопируйте и вставьте сгенерированный в предыдущей главе токен. +Далее скопируйте все три команды из раздела для существующего репозитория (**... or push an existing repository from the command line**, [2]{.figref}) и выполните их в терминале. Если закрыли терминал или он занят Quarto, [создайте новый терминал](#terminal). -![](./img/04-02-03-git-push.png){width=100%} +Positron предложит войти в GitHub. Выберите [Allow]{.figtext}, +запомните код появившийся в новом окне, затем нажмите [Copy & Continue to Browser]{.figtext}. + +![](./img/SCR-20260830-coos.png){width=100%} + +В открывшемся окне браузера разрешите доступ, введите код и завершите вход. +Вернитесь в Positron. ```{r, include=FALSE} -#
В чем разница между HTTPS и SSH? +#
В чём разница между HTTPS и SSH? #
``` -Мы связали наш локальный репозиторий с удаленным при помощи команды **remote add** --- это необходимо было сделать один раз. -И выполнили команду **push** --- отправить сделанные фиксации в удаленный репозиторий, это необходимо делать регулярно и для этого в интерфейсе RStudio есть кнопка на панели [Git]{.figtext}. +Мы связали наш локальный репозиторий с удаленным при помощи команды `git remote add` --- это необходимо было сделать один раз. +И выполнили команду `git push` --- отправить локальные коммиты в удаленный репозиторий, это необходимо делать регулярно и для этого Positron есть интерфейс. + Если команды выполнились успешно, файлы были загружены на GitHub. Обновите страницу репозитория и проверьте содержимое файлов. -![](./img/04-02-04-github.png){width=100%} +![](./img/SCR-20260830-dcfe.png){width=100%} diff --git a/04-03-push-pull.Rmd b/04-03-push-pull.Rmd index 1e4b7f4..8ed19a6 100644 --- a/04-03-push-pull.Rmd +++ b/04-03-push-pull.Rmd @@ -7,65 +7,63 @@ # Это не последовательно и запутает, оставить для практики. ``` -На предыдущем шаге мы загрузили изменения из нашего локального репозитория в удаленный репозиторий на GitHub при помощи команды `push` в терминале. +На предыдущем шаге мы загрузили изменения из локального репозитория в удалённый репозиторий на GitHub при помощи команды `git push` в терминале. +Git не синхронизирует изменения автоматически, это необходимо делать вручную. -Git не синхронизирует изменения автоматически, это необходимо делать вручную, используя команду push ил кнопку [Push]{.figtext} в интерфейсе RStudio на панели [Git]{.figtext}. +Создадим и загрузим ещё один коммит. Добавьте в `paper.qmd` перед чанком с графиком короткое пояснение, например: -Создадим и загрузим еще один коммит. Например, добавим небольшой комментарий к коду, чтобы человеку открывшему его впервые было легче разобраться. - -```r -data <- read.csv("penguins.csv") -x <- data$bill_length_mm - -# Ящик с усами для длины клюва - -png("penguins-boxplot.png") -boxplot(x, ylab = "Bill length, mm") -dev.off() +``` +Ящик с усами для длины клюва. ``` -Сохраните и закомитьте файл `penguins.R`. -После чего нажмите кнопку [Push]{.figtext} в верхнем правом углу. +Сохраните и закомитьте файл `paper.qmd`. +После чего нажмите кнопку [Sync Changes]{.figtext} на панели [Source Control]{.figtext}. -![](./img/04-03-01-git-push.png){width=100%} +![](./img/SCR-20260830-dpri.png){width=100%} Перейдите на страницу репозитория на GitHub и убедитесь, что коммит был загружен. -Это можно понять по тексту сообщения над списком файлов и по тексту и времени изменения напротив файла `penguins.R`. +Это можно понять по тексту сообщения над списком файлов и по тексту и времени изменения напротив файла `paper.qmd`. -![](./img/04-03-02-github.png){width=100%} +![](./img/SCR-20260830-dqwa.png){width=100%} GitHub позволяет вносить изменения в репозиторий из веб-интерфейса. Эта функция используется редко, потому что код необходимо запускать и проверять на компьютере, но она полезна для небольших правок или загрузки файлов. Создадим при помощи нее новый файл. -Файл README --- это файл, который отображается на главной странице репозитория для краткого описания проекта. Обычно он включает описание данных и скриптов, как начать работу с проектом и тому подобное. +Файл README --- это файл, который отображается на главной странице репозитория для краткого описания проекта. Обычно он включает описание данных и кода, как начать работу с проектом и тому подобное. -Нажмите кнопку [Add a README]{.figtext}. В открывшемся файле введите текст в формате Markdown^[это как RMarkdown, только без возможности выполнения кода на R] (используйте или измените текст ниже) +Нажмите кнопку [Add a README]{.figtext}. В открывшемся файле введите текст в формате Markdown^[в документе Quarto используется тот же синтаксис разметки, но README не выполняет код на R] (используйте или измените текст ниже) и нажмите кнопку [Commit changes]{.figtext} в верхнем правом углу. Откроется окно создания коммита, оставьте текст по умолчанию и подтвердите создание коммита нажатием кнопки [Commit changes]{.figtext} -![](./img/04-03-03-add-readme.png){width=100%} +![](./img/SCR-20260830-dtys.png){width=100%} ```md -# Пингвины «Палмер» 🐧 +# Учебный проект -Этот репозиторий был создан в рамках курса от [Института биоинформатики](bioinf.me/education/stat), -чтобы познакомиться с основами Git — фиксацией изменений, ветвлением и работой с GitHub. +Этот репозиторий был создан в рамках курса [«Основы Git»](https://yoursdearboy.github.io/git-101/), +чтобы познакомиться с фиксацией изменений, ветвлением и работой с GitHub. -В качестве примера использованы данные о длине клюва пингвинов, +В качестве примера использованы данные о длине клюва 🐧 пингвинов, собранные доктором Кристен Горман на станции «Палмер» в Антарктиде. -Содержимое репозитория: +Файлы проекта: -- penguins-boxplot.png — диаграмма ящик с усами, показывающая распределение длины клюва -- penguins.R — скрипт для построения диаграммы -- penguins.csv — данные +- `paper.html` — готовый отчёт +- `paper.qmd` — документ Quarto с кодом +- `data/penguins.csv` — данные ``` -Чтобы загрузить изменения из удаленного репозитория на компьютер используется команда **pull**. +Загрузить изменения из удалённого репозитория можно двумя способами: выполнить команду `git pull` в терминале или нажать кнопку [Pull]{.figtext} справа от заголовка [Graph]{.figtext} на панели [Source Control]{.figtext} в Positron. + +::: {style="float: left; clear: both; width: 200px; margin-right: 20px;"} +![](./img/SCR-20260830-dzhz.png){width=100%} +::: + +Загрузите изменения любым из этих способов. +Если загрузка прошла успешно, в журнале появится коммит созданный через GitHub, а в списке файлов `README.md`. -Вернитесь в RStudio и на панели [Git]{.figtext} нажмите кнопку [Pull]{.figtext}. -Если команда выполнилась успешно, в списке файлов появится файл `README.md`, -а в журнале --- коммит созданный через GitHub. +::: {.clearfix} +::: Как и в случае с переключением веток, Git откажется загружать изменения и выдаст ошибку, если в рабочей папке имеются незафиксированные изменения, которые конфликтуют с загружаемыми. diff --git a/04-04-pull-request.Rmd b/04-04-pull-request.Rmd index 71ab9a6..00db24a 100644 --- a/04-04-pull-request.Rmd +++ b/04-04-pull-request.Rmd @@ -4,51 +4,49 @@ Pull Request --- это механизм GitHub для слияния веток Орнитолог проходящий мимо нашего репозитория обратит внимание, что длину клюва пингвина лучше рассматривать в зависимости от пола. Он даже может предложить необходимые изменения при помощи Pull Request. -Создайте ветку с названием `adjust-by-sex` при помощи кнопки [New branch]{.figtext} на панели [Git]{.figtext} в RStudio. Убедитесь, что справа от кнопки вместо названия ветки по умолчанию `main` выводится название созданной ветки `adjust-by-sex`. +Создайте ветку с названием `adjust-by-sex`, как показано в [разделе «Создание ветки»](#git-branch): нажмите `main`в строке состояния Positron и выберите [Create new branch…]{.figtext} Убедитесь, что вместо `main` выводится название созданной ветки `adjust-by-sex`. -![](./img/04-04-01-add-branch.png){width=200} +Замените код в чанке на приведённый ниже. Чтобы посмотреть, что изменилось, выберите файл `paper.qmd` на панели [Source Control]{.figtext}. -Отредактируйте скрипт `penguins.R`, добавив пол в код для построения ящика с усами. Код приведен ниже, не забывайте, что вы можете сравнить изменения по сравнению с оригиналом при помощи кнопки [Diff]{.figtext} на панели [Git]{.figtext}. +```{r, eval=FALSE} +data <- read.csv("data/penguins.csv") -```r -data <- read.csv("penguins.csv") -x <- data$bill_length_mm +x <- data$bill_len g <- data$sex -png("penguins-boxplot.png") boxplot(x ~ g, xlab = "Sex", ylab = "Bill length, mm") -dev.off() ``` -Сохраните и выполните скрипт `penguins.R`. -Создайте коммит включив в него скрипт и обновленную диаграмму `penguins-boxplot.png`. +Сохраните файл и нажмите [Preview]{.figtext}, чтобы обновить отчёт. +Создайте коммит, включив в него `paper.qmd` и `paper.html`. +После создания коммита выберите [Publish Branch]{.figtext} на панели [Source Control]{.figtext}. -![](./img/04-04-02-git-commit.png){width=100%} +![](./img/SCR-20260830-ejim.png){width=100%} -После создания коммита нажмите кнопку [Push]{.figtext} в верхнем правом углу или на панели [Git]{.figtext}. Так как у вас полные права на редактирование репозитория, то новая ветка будет загружена на GitHub. Прохожему орнитологу пришлось бы создать свою копию репозитория или просить дать доступ средствами GitHub. +Так как у вас полные права на редактирование репозитория, то новая ветка будет загружена на GitHub. +Прохожему орнитологу пришлось бы создать свою копию репозитория или просить дать доступ средствами GitHub. -Перейдите на страницу репозитория в GitHub и убедитесь, что ветка была загружена и содержит сделанные измнения, для этого выберите ее в выпадающем меню появляющемся при нажатии кнопки с названием ветки [main]{.figtext}. +Перейдите на страницу репозитория в GitHub и убедитесь, что ветка содержит сделанные измнения, для этого выберите ее в выпадающем меню появляющемся при нажатии кнопки с названием ветки [main]{.figtext}. -![](img/04-04-03-github-branch.png){width=100%} +![](./img/SCR-20260830-ekqj.png){width=100%} При просмотре ветки отличной от основной, GitHub предложит создать из нее **Pull Request** --- предложение автору репозитория слить изменения из этой ветки. Нажмите кнопку [Contribute]{.figtext} и в выпадающем меню выберите [Open pull request]{.figtext}. -![](img/04-04-04-github-pr.png){width=100%} +![](./img/SCR-20260830-ektf.png){width=100%} GitHub предложит ввести заголовок и описание предлагаемых изменений, правило хорошего тона кратко описать причину изменений и суть предлагаемого решения. А также, прокрутите страницу создания Pull Request и проверьте изменения, которые вы предлагаете, после чего нажмите кнопку [Create pull Request]{.figtext} под полем с описанием. -![](img/04-04-05-github-pr.png){width=100%} +![](./img/SCR-20260830-elgi.png){width=100%} На странице Pull Request владельцу репозитория доступна опция слить предложенные изменения. Нажмите кнопку [Merge pull request]{.figtext} внизу страницы. -В открывшемся окне GitHub предложить ввести текст коммита, как если бы мы делали слияние ветки в терминале. Оставьте или измените текст и нажмите кнопку [Confirm merge]{.figtext} +В открывшемся окне GitHub предложить ввести текст коммита, как если бы мы делали слияние ветки в Positron. Оставьте или измените текст и нажмите кнопку [Confirm merge]{.figtext} После успешного слияния ветку можно удалить. ![](img/04-04-06-merge-pr.png){width=100%} ![](img/04-04-07-merge-pr.png){width=100%} ![](img/04-04-08-merge-pr.png){width=100%} -Вернемся к нашему проекту в RStudio. -Слияние было выполнено онлайн на GitHub, а значит необходимо загрузить изменения в наш локальный репозиторий, т.е. сделать pull. -Переключитесь на ветку `main` при помощи панели [Git]{.figtext} и нажмите кнопку [Pull]{.figtext}. -Убедитесь, что теперь ветка `main` содержит актуальные изменения в файлах `penguins.R` и `penguins-boxplot.png`. +Вернёмся к проекту в Positron. Мы выполнили слияние на GitHub, поэтому локальный репозиторий ещё не содержит новых изменений. +Переключитесь на `main` при помощи строки состояния и загрузите изменения, как в [предыдущей главе](#git-push-pull), нажав [Pull]{.figtext}. +Убедитесь, что файлы `paper.qmd` и `paper.html` обновились. diff --git a/04-05-clone.Rmd b/04-05-clone.Rmd index f22c4ab..f023465 100644 --- a/04-05-clone.Rmd +++ b/04-05-clone.Rmd @@ -10,25 +10,14 @@ Нажмите кнопку [Code]{.figtext} на странице репозитория, убедитесь что выбрана опция **HTTPS** и скопируйте адрес. -![](./img/04-03-05-new-project.png){width="600px"} +![Меню Code на GitHub: выбрана вкладка HTTPS и показан адрес репозитория. Откройте опубликованный репозиторий и нажмите Code]() -Создадим проект RStudio. -В верхнем меню выберите [File → New Project]{.figtext}. -В появившемся окне выберите [Version Control]{.figtext} и далее [Git]{.figtext}. -В поле [Repository URL]{.figtext} вставьте адрес репозитория. -В поле [Project directory name]{.figtext} укажите название папки для проекта --- -т.к. папка `penguins` уже существует, используем название `penguins2`. -Откроется окно проекта, RStudio готова к работе. +Создадим копию проекта в Positron. +Откройте новое окно без проекта и в палитре команд выберите [Workspaces: New Folder from Git…]{.figtext}. +Выберите [Clone from GitHub]{.figtext} и свой репозиторий `r-course` или вставьте скопированный адрес. +Укажите другую родительскую папку, чтобы новая копия не оказалась внутри уже открытого проекта. +После загрузки нажмите [Open]{.figtext}. - - - - - - - - - -
![](./img/04-03-01-new-project.png){width="320px"}![](./img/04-03-02-new-project.png){width="320px"}
![](./img/04-03-03-new-project.png){width="320px"}![](./img/04-03-04-new-project.png){width="320px"}
+![Окно Workspaces: New Folder from Git в Positron: выбран репозиторий r-course и папка для новой копии. Выполните Workspaces: New Folder from Git… в новом окне Positron]() Мы склонировали удаленный репозиторий на компьютер и теперь можем работать с ним как с оригинальным проектом --- делать коммиты, загружать изменения в удаленный репозиторий (push) и из него (pull). diff --git a/04-06-conclusion.Rmd b/04-06-conclusion.Rmd index bf1b66e..74990b2 100644 --- a/04-06-conclusion.Rmd +++ b/04-06-conclusion.Rmd @@ -7,7 +7,7 @@ Диаграмма ниже поможет запомнить как соотносятся действия, которые мы изучили: [1) создание коммитов](#git-commit), [2) работа с ветками](#branch) и [3) синхронизация с удаленным репозиторием](#git-push-pull). -![](./img/04-06-sequence.png){width=100%} +![Связь коммитов, веток и синхронизации с удалённым репозиторием](./img/04-06-sequence.png){width=100%} Рекомендуем использовать Git в своих проектах и не бояться экспериментировать с ветками. Это помогает структурировать рабочий процесс, делает анализ данных воспроизводимым и облегчает командную работу. diff --git a/05-01-faq.Rmd b/05-01-faq.Rmd index 128bc53..e3b9840 100644 --- a/05-01-faq.Rmd +++ b/05-01-faq.Rmd @@ -34,7 +34,7 @@ ::: Создайте новую ветку - она будет содержать набор коммитов, который вы имеете сейчас, -при помощи RStudio или командой ниже. +при помощи Positron или командой ниже. ```sh git branch some @@ -42,7 +42,7 @@ git branch some Важно! Убедитесь в том, что создали ветку. Для этого посмотрите журнал или команду `git log` и найдите напротив текущего коммита надпись с названием созданной ветки. -Вернитесь на оригинальную ветку, как правило это `main`, при помощи RStudio или команды ниже. +Вернитесь на оригинальную ветку, как правило это `main`, при помощи Positron или команды ниже. ```sh git checkout main diff --git a/05-02-references.Rmd b/05-02-references.Rmd index b1460ee..4d30e57 100644 --- a/05-02-references.Rmd +++ b/05-02-references.Rmd @@ -1,5 +1,8 @@ # Ссылки {#references} +- [Документация Positron](https://positron.posit.co/welcome.html) --- официальное руководство по интерфейсу Positron. +- [Git Version Control](https://positron.posit.co/git.html) --- работа с Git в Positron. +- [Quarto](https://positron.posit.co/quarto.html) --- работа с документами `.qmd` в Positron. - [Pro Git](https://git-scm.com/book/en/v2) --- небольшая книга рекомендованная разработчиками Git. Из нее вы узнаете о внутреннем устройстве Git и научитесь работать с командой `git` в терминале. Пригодятся главы 1-3 и глава 6. - [Happy Git and GitHub for the useR](https://happygitwithr.com/) --- материалы практического курса по Git с конференции Posit. - [Git Cheatsheet](https://ndpsoftware.com/git-cheatsheet.html#loc=local_repo;) - интерактивная шпаргалка. diff --git a/05-03-webhooks.Rmd b/05-03-webhooks.Rmd index eae5442..24e6d3e 100644 --- a/05-03-webhooks.Rmd +++ b/05-03-webhooks.Rmd @@ -6,7 +6,7 @@ GitHub отправит информацию о событии на указан Для обработки событий по указанному адресу должна работать программа (веб-сервер). Многие сервисы, например Slack или Microsoft Teams, поддерживают таким образом отправку уведомлений в рабочий чат. -Для Telegram можно воспользоваться ботом [@octo8bot](https://t.me/octo8bot). +Для Telegram можно воспользоваться ботом [\@octo8bot](https://t.me/octo8bot). Добавьте бота в чат и скопируйте присланный им адрес. diff --git a/AGENTS.md b/AGENTS.md index 4eb51fd..0093eef 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -15,7 +15,7 @@ This is an onboarding course for the Institute of Bioinformatics programme «Б - `make dev` serves the Bookdown site locally and rebuilds it while editing. - `R -e 'rmarkdown::render("practice/workshop_notebook.Rmd")'` renders an individual practice notebook when that material changes. -There is no separate test suite. A clean successful render is the primary check; inspect the changed pages in `docs/` and verify chapter links, code blocks, citations, and image paths before committing. +Do not build the book or update `docs/` while working on this repository: change the source Rmd files only. The user will render the book themselves. ## Writing, Code Style & Naming @@ -23,4 +23,4 @@ Follow the existing R Markdown style: Russian prose, concise headings, and runna ## Commit & Pull Request Guidelines -Recent history uses short, imperative Russian messages, e.g. `Добавил рендеринг Rmd` or `Поправил формулировки`. Keep commits focused; use merge commits only for merges. Pull requests should explain the instructional change, list affected chapters/practice files, and include rendered `docs/` updates for source changes. Add before/after screenshots for visual changes and link the relevant issue or lesson request when available. +Recent history uses short, imperative Russian messages, e.g. `Добавил рендеринг Rmd` or `Поправил формулировки`. Keep commits focused; use merge commits only for merges. Pull requests should explain the instructional change and list affected chapters/practice files. Add before/after screenshots for visual changes and link the relevant issue or lesson request when available. diff --git a/Makefile b/Makefile index da11b6d..84dac92 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,14 @@ +.PHONY: all test practice build dev + all: build +test: + python3 -m unittest discover -s tests -v + python3 bin/check_course.py + +practice: + quarto render practice/workshop_notebook.qmd --execute-dir practice/assets + build: R -e 'bookdown::render_book(output_dir="docs")' diff --git a/README.md b/README.md index fd507de..33a1e88 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,13 @@ -# Практикум по Git и тулам для ИБ 2024 +# Практикум по Git и тулам для ИБ Слайды [slides.pptx](./slides.pptx) или [slides.pdf](./slides.pdf). Использованные источники ниже. +## Курс + +Курс «Основы Git » продолжает учебный проект курса «Введение в автоматизацию обработки данных на R»: студенты сохраняют накопленные файлы в Git и продолжают анализ пингвинов. + ## Софт - GitKraken - космический корабль по управлению гитом, но довольно friendly diff --git a/_bookdown.yml b/_bookdown.yml index 532ba7b..b722271 100644 --- a/_bookdown.yml +++ b/_bookdown.yml @@ -2,6 +2,28 @@ book_filename: "git-101" new_session: true before_chapter_script: _common.R delete_merged_file: true +rmd_files: + - index.Rmd + - 01-01-about.Rmd + - 01-02-install.Rmd + - 01-03-shell.Rmd + - 02-01-init.Rmd + - 02-02-commit.Rmd + - 02-03-practice.Rmd + - 02-04-log-n-diff.Rmd + - 03-01-branches.Rmd + - 03-02-checkout.Rmd + - 03-03-merge.Rmd + - 03-04-conclusion.Rmd + - 04-01-github.Rmd + - 04-02-remote.Rmd + - 04-03-push-pull.Rmd + - 04-04-pull-request.Rmd + # - 04-05-clone.Rmd + - 04-06-conclusion.Rmd + - 05-01-faq.Rmd + - 05-03-webhooks.Rmd + - 05-02-references.Rmd language: ui: chapter_name: "Глава " diff --git a/bin/check_course.py b/bin/check_course.py new file mode 100644 index 0000000..dcdd1f9 --- /dev/null +++ b/bin/check_course.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +"""Static checks for the reader-facing course sources.""" + +from __future__ import annotations + +from html.parser import HTMLParser +from pathlib import Path +import re +import sys +from urllib.parse import unquote, urlsplit + + +ROOT = Path(__file__).resolve().parents[1] +SOURCES = sorted(ROOT.glob("*.Rmd")) +PRACTICE_MIGRATED = (ROOT / "practice" / "workshop_notebook.qmd").exists() +PRACTICE_SOURCES = ( + sorted((ROOT / "practice").rglob("*.qmd")) + + sorted((ROOT / "practice").glob("*.patch")) + if PRACTICE_MIGRATED + else [] +) + + +class LinkParser(HTMLParser): + def __init__(self) -> None: + super().__init__() + self.links: list[str] = [] + + def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None: + if tag != "a": + return + href = dict(attrs).get("href") + if href: + self.links.append(href) + + +def fail(message: str, failures: list[str]) -> None: + failures.append(message) + + +def main() -> int: + failures: list[str] = [] + for source in SOURCES: + text = source.read_text(encoding="utf-8") + if "%>%" in text: + fail(f"{source.name}: используется %>%", failures) + if "Rstudio" in text: + fail(f"{source.name}: название RStudio написано с ошибкой", failures) + if "R Markdown" in text or "RMarkdown" in text: + fail(f"{source.name}: осталось упоминание R Markdown", failures) + for match in re.finditer(r"!\[([^\]]*)\]\(([^)]*)\)", text): + alt, target = match.groups() + if not alt.strip() and not target.strip(): + fail(f"{source.name}: пустая ссылка на изображение", failures) + if target.strip(): + image_path = (source.parent / unquote(target.strip())).resolve() + if not image_path.exists(): + fail(f"{source.name}: не найдено изображение {target}", failures) + + for source in PRACTICE_SOURCES: + text = source.read_text(encoding="utf-8") + relative = source.relative_to(ROOT) + if "%>%" in text: + fail(f"{relative}: используется %>%", failures) + if "Rstudio" in text: + fail(f"{relative}: название RStudio написано с ошибкой", failures) + if "R Markdown" in text or "RMarkdown" in text: + fail(f"{relative}: осталось упоминание R Markdown", failures) + if ".Rmd" in text: + fail(f"{relative}: активный файл ссылается на .Rmd", failures) + + generator = (ROOT / "bin" / "create_course_project.py").read_text(encoding="utf-8") + if "%>%" in generator: + fail("create_course_project.py: используется %>%", failures) + if 'read.csv("data/penguins.csv")' not in generator: + fail("create_course_project.py: paper.qmd читает данные не из data/penguins.csv", failures) + if "mean(data$bill_len)" not in generator: + fail("create_course_project.py: состояние paper не вычисляет среднюю длину клюва", failures) + if "embed-resources: true" not in generator: + fail("create_course_project.py: HTML-отчёт не встраивает ресурсы", failures) + if 'write_html_report(target, "penguins-hist.png")' not in generator: + fail("create_course_project.py: состояние histogram не создаёт paper.html", failures) + if 'write_paper(target, "visualization")' not in generator: + fail("create_course_project.py: нет состояния с тремя вариантами гистограммы", failures) + if 'write_html_report(target, "penguins-boxplot.png")' not in generator: + fail("create_course_project.py: ветка boxplot не обновляет paper.html", failures) + if "png(" in generator: + fail("create_course_project.py: paper.qmd сохраняет отдельный PNG", failures) + + docs = ROOT / "docs" + for page in sorted(docs.glob("*.html")): + parser = LinkParser() + parser.feed(page.read_text(encoding="utf-8")) + for href in parser.links: + parsed = urlsplit(href) + if parsed.scheme or parsed.netloc or not parsed.path: + continue + target = (page.parent / unquote(parsed.path)).resolve() + if not target.exists(): + fail(f"{page.relative_to(ROOT)}: не найдена ссылка {href}", failures) + + if failures: + print("\n".join(failures), file=sys.stderr) + return 1 + print(f"Проверено файлов курса и практики: {len(SOURCES) + len(PRACTICE_SOURCES)}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/bin/create_course_project.py b/bin/create_course_project.py new file mode 100644 index 0000000..0e953d0 --- /dev/null +++ b/bin/create_course_project.py @@ -0,0 +1,540 @@ +#!/usr/bin/env python3 +"""Create reproducible checkpoints for the Positron Git course.""" + +from __future__ import annotations + +import argparse +import base64 +import hashlib +import json +import os +from pathlib import Path +import shutil +import subprocess +import sys + + +ROOT = Path(__file__).resolve().parents[1] +STARTER = ROOT / "course-project" / "starter" +OUTPUTS = ROOT / "course-project" / "outputs" +UPDATED_DATA = ROOT / "course-project" / "updates" / "penguins.csv" +MANIFEST = ROOT / "course-project" / "starter-manifest.json" + +LOCAL_STATES = ( + "starter", + "baseline", + "paper", + "visualization", + "histogram", + "boxplot-branch", + "dirty-main", + "conflict", + "merged", +) +GITHUB_STATES = ( + "github-published", + "github-pr", + "github-merged", + "github-webhook", +) +STATES = LOCAL_STATES + GITHUB_STATES + +GIT_ENV = { + "GIT_AUTHOR_NAME": "Участник курса", + "GIT_AUTHOR_EMAIL": "student@example.org", + "GIT_COMMITTER_NAME": "Участник курса", + "GIT_COMMITTER_EMAIL": "student@example.org", +} + + +class CourseProjectError(RuntimeError): + """An expected error that can be shown without a traceback.""" + + +def run( + args: list[str], + *, + cwd: Path | None = None, + env: dict[str, str] | None = None, + check: bool = True, + capture: bool = False, +) -> subprocess.CompletedProcess[str]: + command_env = os.environ.copy() + if env: + command_env.update(env) + result = subprocess.run( + args, + cwd=cwd, + env=command_env, + check=False, + text=True, + stdout=subprocess.PIPE if capture else None, + stderr=subprocess.PIPE if capture else None, + ) + if check and result.returncode != 0: + detail = (result.stderr or result.stdout or "").strip() + if detail: + raise CourseProjectError(f"Команда завершилась с ошибкой: {' '.join(args)}\n{detail}") + raise CourseProjectError(f"Команда завершилась с ошибкой: {' '.join(args)}") + return result + + +def sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as source: + for block in iter(lambda: source.read(1024 * 1024), b""): + digest.update(block) + return digest.hexdigest() + + +def validate_starter(path: Path) -> None: + expected = json.loads(MANIFEST.read_text(encoding="utf-8")) + actual_paths = sorted( + item.relative_to(path).as_posix() + for item in path.rglob("*") + if item.is_file() and ".git" not in item.relative_to(path).parts + ) + expected_paths = sorted(expected) + if actual_paths != expected_paths: + raise CourseProjectError("Состав стартового проекта не совпадает с манифестом") + for relative, metadata in expected.items(): + item = path / relative + if item.stat().st_size != metadata["size"] or sha256(item) != metadata["sha256"]: + raise CourseProjectError(f"Стартовый файл повреждён: {relative}") + + +def initialize_repository(target: Path) -> None: + initialized = run(["git", "init", "-b", "main"], cwd=target, check=False, capture=True) + if initialized.returncode != 0: + run(["git", "init"], cwd=target) + run(["git", "branch", "-m", "main"], cwd=target) + run(["git", "config", "user.name", GIT_ENV["GIT_AUTHOR_NAME"]], cwd=target) + run(["git", "config", "user.email", GIT_ENV["GIT_AUTHOR_EMAIL"]], cwd=target) + + +def copy_starter(target: Path) -> None: + if target.exists(): + raise CourseProjectError(f"Путь уже существует: {target}") + target.parent.mkdir(parents=True, exist_ok=True) + shutil.copytree(STARTER, target, copy_function=shutil.copy2) + try: + validate_starter(target) + initialize_repository(target) + except Exception: + shutil.rmtree(target) + raise + + +def commit(target: Path, message: str, day: int) -> None: + run(["git", "add", "-A"], cwd=target, capture=True) + stamp = f"2026-09-{day:02d}T09:00:00+03:00" + run( + ["git", "commit", "-m", message], + cwd=target, + env={**GIT_ENV, "GIT_AUTHOR_DATE": stamp, "GIT_COMMITTER_DATE": stamp}, + capture=True, + ) + + +def write_paper(target: Path, version: str) -> None: + bodies = { + "paper": '''--- +title: "Длина клюва пингвинов" +format: + html: + embed-resources: true +--- + +```{r} +data <- read.csv("data/penguins.csv") + +mean(data$bill_len) +``` +''', + "histogram": '''--- +title: "Длина клюва пингвинов" +format: + html: + embed-resources: true +--- + +```{r} +data <- read.csv("data/penguins.csv") +x <- data$bill_len + +hist(x, breaks = seq(30, 60, 2)) +``` +''', + "visualization": '''--- +title: "Длина клюва пингвинов" +format: + html: + embed-resources: true +--- + +```{r} +data <- read.csv("data/penguins.csv") + +x <- data$bill_len + +hist(x, breaks = seq(30, 60, 3)) +hist(x, breaks = seq(30, 60, 2)) +hist(x, breaks = seq(30, 60, 1)) +``` +''', + "histogram-labelled": '''--- +title: "Длина клюва пингвинов" +format: + html: + embed-resources: true +--- + +```{r} +data <- read.csv("data/penguins.csv") +x <- data$bill_len + +hist(x, breaks = seq(30, 60, 2), xlab = "Bill length, mm") +``` +''', + "boxplot": '''--- +title: "Длина клюва пингвинов" +format: + html: + embed-resources: true +--- + +```{r} +data <- read.csv("data/penguins.csv") +x <- data$bill_len + +boxplot(x) +``` +''', + "boxplot-labelled": '''--- +title: "Длина клюва пингвинов" +format: + html: + embed-resources: true +--- + +```{r} +data <- read.csv("data/penguins.csv") +x <- data$bill_len + +boxplot(x, ylab = "Bill length, mm") +``` +''', + "by-sex": '''--- +title: "Длина клюва пингвинов" +format: + html: + embed-resources: true +--- + +```{r} +data <- read.csv("data/penguins.csv") +x <- data$bill_len +g <- data$sex + +boxplot(x ~ g, xlab = "Sex", ylab = "Bill length, mm") +``` +''', + } + (target / "paper.qmd").write_text(bodies[version], encoding="utf-8") + + +def copy_output(target: Path, source: str, destination: str) -> None: + output = target / "out" / destination + output.parent.mkdir(exist_ok=True) + shutil.copy2(OUTPUTS / source, output) + + +def write_html_report(target: Path, chart: str) -> None: + image = base64.b64encode((OUTPUTS / chart).read_bytes()).decode("ascii") + descriptions = { + "penguins-hist.png": "Гистограмма длины клюва пингвинов", + "penguins-boxplot.png": "Ящик с усами для длины клюва пингвинов", + "penguins-boxplot-labelled.png": "Ящик с усами с подписью оси", + "penguins-boxplot-by-sex.png": "Длина клюва пингвинов в зависимости от пола", + } + (target / "paper.html").write_text( + f''' + + + + Длина клюва пингвинов + + +
+

Длина клюва пингвинов

+ {descriptions[chart]} +
+ + +''', + encoding="utf-8", + ) + + +def update_penguin_data(target: Path) -> None: + shutil.copy2(UPDATED_DATA, target / "data" / "penguins.csv") + + +def make_baseline(target: Path) -> None: + commit(target, "Добавил файлы курса по R", 1) + + +def make_paper(target: Path) -> None: + make_baseline(target) + write_paper(target, "paper") + update_penguin_data(target) + commit(target, "Импортировал данные пингвинов", 2) + + +def make_visualization(target: Path) -> None: + make_paper(target) + write_paper(target, "visualization") + commit(target, "Добавил гистограммы для длины клюва", 3) + + +def make_histogram(target: Path) -> None: + make_visualization(target) + write_paper(target, "histogram") + write_html_report(target, "penguins-hist.png") + commit(target, "Собрал отчёт о длине клюва", 4) + + +def make_boxplot_branch(target: Path) -> None: + make_histogram(target) + run(["git", "switch", "-c", "boxplot"], cwd=target, capture=True) + write_paper(target, "boxplot") + write_html_report(target, "penguins-boxplot.png") + commit(target, "Заменил гистограмму на ящик с усами", 5) + + +def make_dirty_main(target: Path) -> None: + make_boxplot_branch(target) + run(["git", "switch", "main"], cwd=target, capture=True) + write_paper(target, "histogram-labelled") + + +def make_conflict(target: Path) -> None: + make_dirty_main(target) + commit(target, "Добавил подпись оси гистограммы", 6) + merged = run(["git", "merge", "boxplot"], cwd=target, check=False, capture=True) + if merged.returncode == 0: + raise CourseProjectError("Не удалось создать учебный конфликт слияния") + + +def make_merged(target: Path) -> None: + make_conflict(target) + write_paper(target, "boxplot-labelled") + write_html_report(target, "penguins-boxplot-labelled.png") + commit(target, "Слил ветку boxplot", 7) + + +def make_adjust_by_sex(target: Path) -> None: + make_merged(target) + run(["git", "switch", "-c", "adjust-by-sex"], cwd=target, capture=True) + write_paper(target, "by-sex") + write_html_report(target, "penguins-boxplot-by-sex.png") + commit(target, "Сгруппировал пингвинов по полу", 8) + + +def build_local_state(target: Path, state: str) -> None: + builders = { + "starter": lambda path: None, + "baseline": make_baseline, + "paper": make_paper, + "visualization": make_visualization, + "histogram": make_histogram, + "boxplot-branch": make_boxplot_branch, + "dirty-main": make_dirty_main, + "conflict": make_conflict, + "merged": make_merged, + } + builders[state](target) + + +def ensure_gh_auth() -> None: + if shutil.which("gh") is None: + raise CourseProjectError("Не найден GitHub CLI (gh). Установите его и повторите запуск") + status = run(["gh", "auth", "status", "-h", "github.com"], check=False) + if status.returncode != 0: + print("Откроется браузер для входа в GitHub.") + run(["gh", "auth", "login", "--web", "-h", "github.com", "-p", "https"]) + run(["gh", "auth", "status", "-h", "github.com"]) + + +def ensure_remote_absent(repository: str) -> None: + existing = run( + ["gh", "repo", "view", repository, "--json", "nameWithOwner"], + check=False, + capture=True, + ) + if existing.returncode == 0: + raise CourseProjectError(f"Репозиторий GitHub уже существует: {repository}") + detail = (existing.stderr or existing.stdout or "").strip() + missing_markers = ("Could not resolve to a Repository", "HTTP 404", "Not Found") + if detail and not any(marker in detail for marker in missing_markers): + raise CourseProjectError(f"Не удалось проверить репозиторий GitHub:\n{detail}") + + +def publish_repository(target: Path, repository: str, visibility: str) -> None: + current_branch = run( + ["git", "branch", "--show-current"], cwd=target, capture=True + ).stdout.strip() + if current_branch != "main": + run(["git", "switch", "main"], cwd=target, capture=True) + run( + [ + "gh", + "repo", + "create", + repository, + "--source=.", + "--remote=origin", + "--push", + f"--{visibility}", + ], + cwd=target, + ) + run(["git", "push", "--all", "origin"], cwd=target) + if current_branch != "main": + run(["git", "switch", current_branch], cwd=target, capture=True) + + +def create_pull_request(target: Path, repository: str) -> str: + run(["git", "push", "-u", "origin", "adjust-by-sex"], cwd=target) + created = run( + [ + "gh", + "pr", + "create", + "--repo", + repository, + "--base", + "main", + "--head", + "adjust-by-sex", + "--title", + "Сгруппировал пингвинов по полу", + "--body", + "Ящик с усами теперь показывает распределение длины клюва отдельно для каждого пола.", + ], + cwd=target, + capture=True, + ) + return created.stdout.strip() + + +def add_webhook(repository: str, url: str, secret: str | None) -> None: + args = [ + "gh", + "api", + "--method", + "POST", + f"repos/{repository}/hooks", + "-f", + "name=web", + "-F", + "active=true", + "-f", + f"config[url]={url}", + "-f", + "config[content_type]=json", + "-f", + "events[]=pull_request", + ] + if secret: + args.extend(["-f", f"config[secret]={secret}"]) + run(args) + + +def build_github_state( + target: Path, + state: str, + repository: str, + visibility: str, + webhook_url: str | None, + webhook_secret: str | None, +) -> None: + if state == "github-published": + make_merged(target) + publish_repository(target, repository, visibility) + return + + make_adjust_by_sex(target) + publish_repository(target, repository, visibility) + + if state == "github-pr": + return + + if state == "github-webhook": + if not webhook_url: + raise CourseProjectError("Для github-webhook нужен параметр --webhook-url") + add_webhook(repository, webhook_url, webhook_secret) + + pull_request = create_pull_request(target, repository) + print(f"Pull request: {pull_request}") + + if state == "github-merged": + run( + ["gh", "pr", "merge", pull_request, "--repo", repository, "--merge", "--delete-branch"], + cwd=target, + ) + run(["git", "switch", "main"], cwd=target) + run(["git", "pull", "--ff-only", "origin", "main"], cwd=target) + + +def parse_args(argv: list[str] | None = None) -> argparse.Namespace: + parser = argparse.ArgumentParser( + description="Создать проект для выбранной контрольной точки курса Git", + ) + parser.add_argument("target", type=Path, help="новая папка проекта") + parser.add_argument("--state", choices=STATES, default="starter") + parser.add_argument("--repo", help="репозиторий GitHub в формате OWNER/NAME") + parser.add_argument("--visibility", choices=("private", "public"), default="private") + parser.add_argument("--webhook-url") + parser.add_argument("--webhook-secret") + return parser.parse_args(argv) + + +def main(argv: list[str] | None = None) -> int: + args = parse_args(argv) + target = args.target.expanduser().resolve() + + try: + if target.exists(): + raise CourseProjectError(f"Путь уже существует: {target}") + + if args.state in GITHUB_STATES: + if not args.repo or args.repo.count("/") != 1: + raise CourseProjectError("Для GitHub-состояния укажите --repo OWNER/NAME") + if args.state == "github-webhook" and not args.webhook_url: + raise CourseProjectError("Для github-webhook нужен параметр --webhook-url") + ensure_gh_auth() + ensure_remote_absent(args.repo) + + copy_starter(target) + if args.state in LOCAL_STATES: + build_local_state(target, args.state) + else: + build_github_state( + target, + args.state, + args.repo, + args.visibility, + args.webhook_url, + args.webhook_secret, + ) + except CourseProjectError as error: + print(f"Ошибка: {error}", file=sys.stderr) + return 1 + + print(f"Создано состояние {args.state}: {target}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/course-project/README.md b/course-project/README.md new file mode 100644 index 0000000..a09d837 --- /dev/null +++ b/course-project/README.md @@ -0,0 +1,11 @@ +# Эталон проекта студента + +`starter/` — состояние проекта сразу после последнего задания R-курса. Это не очищенный шаблон: старые `.R`, документы Quarto, данные и созданные результаты сохранены. + +Генератор сначала копирует дерево как есть, сверяет `starter-manifest.json`, затем создаёт локальную `.git`. В `starter` история пуста, а все накопленные файлы ожидают первого коммита. Следующие состояния добавляют только работу Git-курса. + +Файл `build_outputs.R` пересоздаёт эталонные PNG для контрольных состояний. Он не меняет стартовый `out/hist.png`, полученный по заданию R-курса. + +Файл `updates/penguins.csv` содержит данные после измерения двух пропущенных значений длины клюва. Генератор заменяет им стартовый файл при создании состояния `paper`, чтобы история совпадала с заданием раздела «Импорт данных». + +Если задания R-курса изменились, обновите `starter/`, пересоздайте результаты, затем осознанно обновите размеры и SHA-256 в манифесте. Не преобразовывайте содержимое в «более удобный» формат. diff --git a/course-project/build_outputs.R b/course-project/build_outputs.R new file mode 100644 index 0000000..a0d9378 --- /dev/null +++ b/course-project/build_outputs.R @@ -0,0 +1,19 @@ +data <- read.csv("course-project/updates/penguins.csv") +x <- data$bill_len +g <- data$sex + +png("course-project/outputs/penguins-hist.png") +hist(x, breaks = seq(30, 60, 2)) +dev.off() + +png("course-project/outputs/penguins-boxplot.png") +boxplot(x) +dev.off() + +png("course-project/outputs/penguins-boxplot-labelled.png") +boxplot(x, ylab = "Bill length, mm") +dev.off() + +png("course-project/outputs/penguins-boxplot-by-sex.png") +boxplot(x ~ g, xlab = "Sex", ylab = "Bill length, mm") +dev.off() diff --git a/course-project/outputs/penguins-boxplot-by-sex.png b/course-project/outputs/penguins-boxplot-by-sex.png new file mode 100644 index 0000000..5481553 Binary files /dev/null and b/course-project/outputs/penguins-boxplot-by-sex.png differ diff --git a/course-project/outputs/penguins-boxplot-labelled.png b/course-project/outputs/penguins-boxplot-labelled.png new file mode 100644 index 0000000..3f18c0f Binary files /dev/null and b/course-project/outputs/penguins-boxplot-labelled.png differ diff --git a/course-project/outputs/penguins-boxplot.png b/course-project/outputs/penguins-boxplot.png new file mode 100644 index 0000000..a3e7cd8 Binary files /dev/null and b/course-project/outputs/penguins-boxplot.png differ diff --git a/course-project/outputs/penguins-hist.png b/course-project/outputs/penguins-hist.png new file mode 100644 index 0000000..7e23c29 Binary files /dev/null and b/course-project/outputs/penguins-hist.png differ diff --git a/course-project/starter-manifest.json b/course-project/starter-manifest.json new file mode 100644 index 0000000..bc2f871 --- /dev/null +++ b/course-project/starter-manifest.json @@ -0,0 +1,66 @@ +{ + ".gitignore": { + "sha256": "a57247db5f9eae084a417e62d6977d54de690ef16026a773dc2771410d9b90dd", + "size": 62 + }, + "analysis.qmd": { + "sha256": "47a6a626f3ba7943b65c45c36c0cbe26319f74f0415df6d6df6183fd4bf813f2", + "size": 1460 + }, + "base.R": { + "sha256": "ea8717357591f98abf37f4ca76902af4e4dc0b3050dc9ed8b6fe2e61aaa21b50", + "size": 202 + }, + "coffee.R": { + "sha256": "cddb0a7bb8ac3692dc660f715841075e23bf564b318d9ef059e65f9fe35b94b2", + "size": 55 + }, + "data/data.rds": { + "sha256": "96e2953c8c11282cb984551dd5bebc0efbd75ed767ed845598731343677d4d28", + "size": 5183 + }, + "data/data_csv.csv": { + "sha256": "2bc1d926890c6364d0708198e738b3915976a8784aa26d297460cdbc710610b8", + "size": 10909 + }, + "data/data_csv2.csv": { + "sha256": "de4b324352f8ca173cd0a486eba481a1f9fcc2f4762d22dfaf205e141ee37c26", + "size": 12973 + }, + "data/data_excel.xlsx": { + "sha256": "e4a6280d6e9038f18f8b922be81587e27f944e9ec0e686e3080a20adbd0815dc", + "size": 19971 + }, + "data/data_rds.rds": { + "sha256": "ed3d699fd0415427dacb4c3bc23dd49775b51043d86af9e4aaa2278c87e826c1", + "size": 11661 + }, + "data/data_tsv.tsv": { + "sha256": "ad6c18f0977516f7c5ddee689dc6a8df31f46cc083fcbb49128f410ae75d3153", + "size": 10314 + }, + "data/penguins.csv": { + "sha256": "310b5783fe528ad4b7635bad2973b31ed0aafa02619492978bc14bab5c3d7f64", + "size": 17242 + }, + "out/hist.png": { + "sha256": "17adbf4165d1300c52fd228d328b28fcf23c1430c209aaec677b720a603a85c6", + "size": 24180 + }, + "penguins.R": { + "sha256": "50b476daf079ea372edf3e79e8338ad0b5f697e20009af9eeb6e2ac9a9370763", + "size": 206 + }, + "report.html": { + "sha256": "2267e9e1a963017b2f64aae888c0eb6ea444c1f84b100f806cb7c087fb037f92", + "size": 1200715 + }, + "report.qmd": { + "sha256": "f7b86181ea166cbed3e67dcc7cb4317b798592424435330ea80ed8fca2af43f4", + "size": 467 + }, + "tables.qmd": { + "sha256": "fbc78bd8d0c204944c3abd3fa5ecfc3b44e90d74edb5a277f699a4008afec5f9", + "size": 937 + } +} diff --git a/course-project/starter/.gitignore b/course-project/starter/.gitignore new file mode 100644 index 0000000..d7f8b0b --- /dev/null +++ b/course-project/starter/.gitignore @@ -0,0 +1,7 @@ +.Rhistory +.RData +.Ruserdata +.DS_Store +report_files/ +*_cache/ + diff --git a/course-project/starter/analysis.qmd b/course-project/starter/analysis.qmd new file mode 100644 index 0000000..6c97394 --- /dev/null +++ b/course-project/starter/analysis.qmd @@ -0,0 +1,47 @@ +--- +title: "Анализ медицинских данных" +format: html +--- + +```{r} +library(tidyverse) +``` + +```{r} +data <- read_tsv("data/data_tsv.tsv", show_col_types = FALSE) +data$Группа <- factor(data$Группа) +data$Пол <- factor(data$Пол) +data$`Группа крови` <- factor( + data$`Группа крови`, + levels = c("O (I)", "A (II)", "B (III)", "AB (IV)") +) +``` + +```{r} +statistics <- list( + `Количество субъектов` = ~ length(.x), + `Количество (есть данные)` = ~ sum(!is.na(.x)), + `Нет данных` = ~ sum(is.na(.x)), + `Ср. знач.` = ~ mean(.x, na.rm = TRUE), + `Станд. отклон.` = ~ sd(.x, na.rm = TRUE), + `мин.` = ~ min(.x, na.rm = TRUE), + `макс.` = ~ max(.x, na.rm = TRUE), + `Медиана` = ~ median(.x, na.rm = TRUE), + `Q1` = ~ quantile(.x, 0.25, na.rm = TRUE), + `Q3` = ~ quantile(.x, 0.75, na.rm = TRUE) +) + +table <- data |> + select(`Группа`, where(is.numeric)) |> + group_by(`Группа`) |> + summarise(across(where(is.numeric), statistics, .names = "{.col}__{.fn}")) |> + mutate(across(-`Группа`, function(x) round(x, 2))) |> + mutate(across(-`Группа`, as.character)) |> + mutate(across(-`Группа`, function(x) replace_na(x, "Н/П*"))) |> + pivot_longer(!`Группа`) |> + separate(name, into = c("Переменная", "Статистика"), sep = "__") |> + rename(`Значение` = value) + +table +``` + diff --git a/course-project/starter/base.R b/course-project/starter/base.R new file mode 100644 index 0000000..b493bc1 --- /dev/null +++ b/course-project/starter/base.R @@ -0,0 +1,10 @@ +my_var1 <- 42 +my_var2 <- 35.25 +my_var3 <- my_var1^2 + my_var2^2 +my_new_var <- my_var1 == my_var2 + +numbers <- c(20, 68, 45, 76, 41, 36, 13, 52, 77, 53, 70, 73) +mean(numbers) +median(numbers) +sd(numbers) + diff --git a/course-project/starter/coffee.R b/course-project/starter/coffee.R new file mode 100644 index 0000000..d0d50e5 --- /dev/null +++ b/course-project/starter/coffee.R @@ -0,0 +1,4 @@ +1.5 * 100 / 2 +1.5 * 100 / 2 / 2 +1.5 * 100 / 2 / 2 / 2 + diff --git a/course-project/starter/data/data.rds b/course-project/starter/data/data.rds new file mode 100644 index 0000000..a21bb8a Binary files /dev/null and b/course-project/starter/data/data.rds differ diff --git a/course-project/starter/data/data_csv.csv b/course-project/starter/data/data_csv.csv new file mode 100644 index 0000000..9986520 --- /dev/null +++ b/course-project/starter/data/data_csv.csv @@ -0,0 +1,101 @@ +"Группа","Возраст","Пол","Рост","Группа крови","Базофилы_E1","Эозинофилы_E1","Гемоглобин_E1","Эритроциты_E1","Базофилы_E2","Эозинофилы_E2","Гемоглобин_E2","Эритроциты_E2" +"Группа 1",31,"Женский",174,"A (II)",0.4222,0.6465,10.6842,4.2573,0.8264,1.6613,11.4051,6.5728 +"Группа 1",28,"Женский",157,"A (II)",0.327,4.9742,9.6169,3.8813,0.7312,5.989,10.3378,6.1968 +"Группа 1",33,"Женский",166,NA,0.7994,3.3875,10.1628,5.0607,1.2036,4.4023,10.8837,7.3762 +"Группа 1",26,"Женский",168,"O (I)",0.0237,4.5403,10.6391,3.8083,0.4279,5.5551,11.36,6.1238 +"Группа 1",33,"Женский",170,"A (II)",0.6636,3.3159,12.259,3.0321,1.0678,4.3307,12.9799,5.3476 +"Группа 1",28,"Мужской",172,"B (III)",0.481,2.7863,12.3529,4.7917,0.8852,3.8011,13.0738,7.1072 +"Группа 1",27,"Мужской",157,"A (II)",0.8899,2.3432,11.2656,3.3619,1.2941,3.358,11.9865,5.6774 +"Группа 1",31,"Мужской",174,NA,0.8576,3.9788,14.8948,4.4598,1.2618,4.9936,15.6157,6.7753 +"Группа 1",23,"Женский",175,"A (II)",0.3832,3.3896,15.6802,4.4339,0.7874,4.4044,16.4011,6.7494 +"Группа 1",29,"Женский",172,"A (II)",0.2812,7.9352,12.9084,4.3275,0.6854,8.95,13.6293,6.643 +"Группа 1",32,"Женский",165,"A (II)",0.8032,2.4649,10.1162,3.4207,1.2074,3.4797,10.8371,5.7362 +"Группа 1",33,"Мужской",171,"B (III)",0.7606,2.8023,11.0011,4.3114,1.1648,3.8171,11.722,6.6269 +"Группа 1",30,"Женский",176,NA,-0.2188,1.2468,12.0861,3.6621,0.1854,2.2616,12.807,5.9776 +"Группа 1",28,"Женский",165,"O (I)",0.517,8.1285,11.4946,2.8699,0.9212,9.1433,12.2155,5.1854 +"Группа 1",25,"Женский",170,"B (III)",0.9893,0.5132,14.4936,4.3594,1.3935,1.528,15.2145,6.6749 +"Группа 1",38,"Женский",167,NA,0.899,2.6541,10.6878,4.9044,1.3032,3.6689,11.4087,7.2199 +"Группа 1",32,"Мужской",177,"B (III)",0.3413,0.8715,16.0903,4.1925,0.7455,1.8863,16.8112,6.508 +"Группа 1",27,"Женский",167,"B (III)",0.4083,3.7789,13.2827,4.5453,0.8125,4.7937,14.0036,6.8608 +"Группа 1",28,"Женский",169,"O (I)",0.3009,2.3743,11.5597,3.1849,0.7051,3.3891,12.2806,5.5004 +"Группа 1",27,"Мужской",158,"B (III)",0.416,3.798,13.4759,5.0699,0.8202,4.8128,14.1968,7.3854 +"Группа 1",28,"Женский",162,"O (I)",0.834,2.5866,12.353,3.7413,1.2382,3.6014,13.0739,6.0568 +"Группа 1",31,"Женский",164,"A (II)",0.8936,4.3898,12.152,3.73,1.2978,5.4046,12.8729,6.0455 +"Группа 1",26,"Мужской",171,NA,0.8364,5.0805,8.6038,4.6658,1.2406,6.0953,9.3247,6.9813 +"Группа 1",34,"Женский",173,NA,0.8969,4.5769,14.0891,3.7455,1.3011,5.5917,14.81,6.061 +"Группа 1",27,"Мужской",169,"O (I)",0.5617,5.6353,11.1436,3.8355,0.9659,6.6501,11.8645,6.151 +"Группа 1",31,"Женский",173,"B (III)",0.8466,5.8133,16.2315,4.5226,1.2508,6.8281,16.9524,6.8381 +"Группа 1",21,"Мужской",156,"A (II)",0.7375,3.6625,10.9569,3.5251,1.1417,4.6773,11.6778,5.8406 +"Группа 1",28,"Мужской",164,NA,0.8984,0.2688,13.7583,3.9492,1.3026,1.2836,14.4792,6.2647 +"Группа 1",27,"Женский",168,"A (II)",-0.0391,1.67,10.4017,3.6078,0.3651,2.6848,11.1226,5.9233 +"Группа 1",33,"Мужской",170,"O (I)",-0.2002,2.1515,9.8202,5.7281,0.204,3.1663,10.5411,8.0436 +"Группа 1",35,"Мужской",155,"A (II)",0.3337,3.4448,12.1903,4.4991,0.7379,4.4596,12.9112,6.8146 +"Группа 1",25,"Мужской",175,NA,0.2541,3.8754,15.2743,4.7965,0.6583,4.8902,15.9952,7.112 +"Группа 1",36,"Женский",169,"O (I)",0.6489,2.2938,9.1329,4.8499,1.0531,3.3086,9.8538,7.1654 +"Группа 1",23,"Женский",166,"O (I)",0.4381,2.5826,11.1547,4.4297,0.8423,3.5974,11.8756,6.7452 +"Группа 1",32,"Женский",162,"B (III)",1.3054,2.9359,13.2145,3.786,1.7096,3.9507,13.9354,6.1015 +"Группа 1",28,"Мужской",165,"O (I)",0.5758,3.1627,10.9963,4.1499,0.98,4.1775,11.7172,6.4654 +"Группа 1",32,"Женский",170,"B (III)",0.2684,1.8568,11.2402,3.3907,0.6726,2.8716,11.9611,5.7062 +"Группа 1",31,"Женский",171,"A (II)",0.4208,4.4054,5.3523,4.011,0.825,5.4202,6.0732,6.3265 +"Группа 1",31,"Женский",181,"B (III)",0.1761,3.0373,9.505,4.7135,0.5803,4.0521,10.2259,7.029 +"Группа 1",25,"Женский",179,"AB (IV)",0.318,1.8673,11.4646,2.8206,0.7222,2.8821,12.1855,5.1361 +"Группа 1",30,"Мужской",156,"AB (IV)",0.0509,0.3804,13.3238,3.7554,0.4551,1.3952,14.0447,6.0709 +"Группа 1",26,"Женский",172,"AB (IV)",0.4853,3.3438,10.5516,4.4054,0.8895,4.3586,11.2725,6.7209 +"Группа 1",33,"Женский",164,"A (II)",1.5915,5.0897,9.7669,4.1358,1.9957,6.1045,10.4878,6.4513 +"Группа 1",34,"Женский",164,"A (II)",0.3361,4.2492,12.4213,4.2117000000000004,0.7403,5.264,13.1422,6.5272 +"Группа 1",24,"Женский",163,NA,0.2666,2.336,15.1213,4.7835,0.6708,3.3508,15.8422,7.099 +"Группа 1",25,"Женский",171,"B (III)",1.454,3.4946,11.9013,4.6613,1.8582,4.5094,12.6222,6.9768 +"Группа 1",23,"Мужской",162,"AB (IV)",0.7981,2.1393,14.1017,2.8917,1.2023,3.1541,14.8226,5.2072 +"Группа 1",35,"Женский",171,"A (II)",0.3588,5.0382,10.6129,4.4047,0.763,6.053,11.3338,6.7202 +"Группа 1",29,"Мужской",175,"O (I)",0.8537,-0.3005,13.205,5.2975,1.2579,0.7143,13.9259,7.613 +"Группа 1",30,"Мужской",171,"A (II)",0.665,1.594,12.6169,5.4316,1.0692,2.6088,13.3378,7.7471 +"Группа 2",37,"Мужской",165,"AB (IV)",0.8954,5.1303,13.5317,2.926,1.2996,6.1451,14.2526,5.2415 +"Группа 2",25,"Женский",168,"O (I)",1.3261,6.8981,13.2712,4.0185,1.7303,7.9129,13.9921,6.334 +"Группа 2",32,"Женский",159,"A (II)",-0.0283,4.0341,8.8472,3.5037,0.3759,5.0489,9.5681,5.8192 +"Группа 2",35,"Мужской",164,"AB (IV)",0.8283,7.0987,10.1555,3.9505,1.2325,8.1135,10.8764,6.266 +"Группа 2",29,"Мужской",170,"O (I)",0.412,6.0201,9.6631,4.0911,0.8162,7.0349,10.384,6.4066 +"Группа 2",34,"Мужской",169,"B (III)",0.3367,3.6771,11.9647,5.2631,0.7409,4.6919,12.6856,7.5786 +"Группа 2",34,"Мужской",161,"A (II)",0.7744,4.405,11.9282,3.2528,1.1786,5.4198,12.6491,5.5683 +"Группа 2",27,"Женский",167,NA,0.1906,3.8312,11.27,5.0763,0.5948,4.846,11.9909,7.3918 +"Группа 2",34,"Женский",175,"AB (IV)",0.4139,-1.048,10.5656,3.9456,0.8181,-0.0332,11.2865,6.2611 +"Группа 2",30,"Мужской",167,"A (II)",0.8407,1.3026,15.1292,3.7485,1.2449,2.3174,15.8501,6.064 +"Группа 2",33,"Женский",162,"A (II)",1.0976,6.3401,10.9379,4.3332,1.5018,7.3549,11.6588,6.6487 +"Группа 2",26,"Мужской",164,"O (I)",0.8849,1.469,12.1955,4.9171,1.2891,2.4838,12.9164,7.2326 +"Группа 2",28,"Мужской",165,"A (II)",1.7186,5.9387,11.2181,4.2957,2.1228,6.9535,11.939,6.6112 +"Группа 2",35,"Мужской",172,"O (I)",1.2805,7.0429,12.3226,4.0218,1.6847,8.0577,13.0435,6.3373 +"Группа 2",22,"Женский",161,NA,0.9704,6.2395,10.6715,4.2513,1.3746,7.2543,11.3924,6.5668 +"Группа 2",34,"Мужской",171,"A (II)",1.1937,2.0692,11.7092,3.3324,1.5979,3.084,12.4301,5.6479 +"Группа 2",27,"Мужской",176,"A (II)",0.6806,3.4455,10.4657,4.775,1.0848,4.4603,11.1866,7.0905 +"Группа 2",32,"Женский",159,"O (I)",0.5602,1.6435,13.3411,4.1875,0.9644,2.6583,14.062,6.503 +"Группа 2",31,"Женский",168,"A (II)",0.7827,3.9147,13.1647,4.7969,1.1869,4.9295,13.8856,7.1124 +"Группа 2",31,"Мужской",168,"B (III)",0.92490000000000006,4.7131,11.0108,3.2465,1.3291,5.7279,11.7317,5.562 +"Группа 2",33,"Мужской",170,"B (III)",1.4613,7.2709,11.7787,4.0559,1.8655,8.2857,12.4996,6.3714 +"Группа 2",30,"Женский",165,"A (II)",0.2669,6.4108,14.4411,4.2103,0.6711,7.4256,15.162,6.5258 +"Группа 2",28,"Мужской",174,"A (II)",0.795,2.6174,10.9779,3.5962,1.1992,3.6322,11.6988,5.9117 +"Группа 2",29,"Мужской",171,"A (II)",0.482,4.9124,10.089,3.2071,0.8862,5.9272,10.8099,5.5226 +"Группа 2",29,"Женский",166,"O (I)",0.6358,4.7582,11.3264,3.5469,1.04,5.773,12.0473,5.8624 +"Группа 2",21,"Мужской",167,"O (I)",0.4371,2.5971,14.2052,4.3911,0.8413,3.6119,14.9261,6.7066 +"Группа 2",29,"Мужской",164,"O (I)",0.6036,6.0198,13.354,4.8232,1.0078,7.0346,14.0749,7.1387 +"Группа 2",33,"Женский",159,"O (I)",0.6529,4.3756,12.875,4.7547,1.0571,5.3904,13.5959,7.0702 +"Группа 2",42,"Женский",161,NA,0.8271,4.902,10.9604,4.7991,1.2313,5.9168,11.6813,7.1146 +"Группа 2",37,"Мужской",160,"A (II)",0.3053,4.7937,10.9401,3.2195,0.7095,5.8085,11.661,5.535 +"Группа 2",38,"Мужской",177,"O (I)",0.2841,4.5635,10.3758,5.1561,0.6883,5.5783,11.0967,7.4716 +"Группа 2",32,"Мужской",160,"A (II)",0.6112,-0.6534,11.9738,3.4066,1.0154,0.3614,12.6947,5.7221 +"Группа 2",28,"Мужской",166,"A (II)",0.6741,3.8194,9.8513,3.0476,1.0783,4.8342,10.5722,5.3631 +"Группа 2",34,"Мужской",163,NA,0.7178,6.2474,12.2265,4.0731,1.122,7.2622,12.9474,6.3886 +"Группа 2",35,"Женский",177,"A (II)",0.7161,6.1906,9.9169,2.8447,1.1203,7.2054,10.6378,5.1602 +"Группа 2",29,"Женский",176,"O (I)",1.1057,1.4231,13.8564,4.1773,1.5099,2.4379,14.5773,6.4928 +"Группа 2",33,"Мужской",170,"A (II)",0.4425,5.8075,10.7608,5.2198,0.8467,6.8223,11.4817,7.5353 +"Группа 2",32,"Мужской",174,NA,0.9519,7.4574,11.4253,3.6331,1.3561,8.4722,12.1462,5.9486 +"Группа 2",33,"Женский",161,"B (III)",1.0887,3.5337,10.8088,3.5177,1.4929,4.5485,11.5297,5.8332 +"Группа 2",32,"Женский",171,"O (I)",0.5839,2.5204,13.1545,4.0298,0.9881,3.5352,13.8754,6.3453 +"Группа 2",28,"Мужской",164,NA,1.0915,0.139,11.7136,4.578,1.4957,1.1538,12.4345,6.8935 +"Группа 2",25,"Мужской",176,"A (II)",0.4885,1.376,13.0178,4.039,0.8927,2.3908,13.7387,6.3545 +"Группа 2",30,"Женский",173,"O (I)",0.1545,4.3131,12.9821,5.1128,0.5587,5.3279,13.703,7.4283 +"Группа 2",32,"Женский",176,"B (III)",0.8272,-1.2272,10.2154,5.0766,1.2314,-0.2124,10.9363,7.3921 +"Группа 2",35,"Женский",169,"A (II)",1.3627,5.9156,11.9732,3.5125,1.7669,6.9304,12.6941,5.828 +"Группа 2",33,"Мужской",159,"AB (IV)",0.6324,5.7865,10.2755,3.6352,1.0366,6.8013,10.9964,5.9507 +"Группа 2",33,"Мужской",167,"O (I)",0.5179,7.4466,13.291,3.8014,0.9221,8.4614,14.0119,6.1169 +"Группа 2",30,"Мужской",164,NA,0.424,8.4344,10.829,3.8113,0.8282,9.4492,11.5499,6.1268 +"Группа 2",34,"Женский",168,"O (I)",0.9505,0.8028,13.4033,3.5868,1.3547,1.8176,14.1242,5.9023 +"Группа 2",30,"Женский",169,NA,0.7031,5.3706,12.2419,3.2039,1.1073,6.3854,12.9628,5.5194 diff --git a/course-project/starter/data/data_csv2.csv b/course-project/starter/data/data_csv2.csv new file mode 100644 index 0000000..025ce36 --- /dev/null +++ b/course-project/starter/data/data_csv2.csv @@ -0,0 +1,101 @@ +"Группа";"Возраст";"Пол";"Рост";"Группа крови";"Базофилы_E1";"Эозинофилы_E1";"Гемоглобин_E1";"Эритроциты_E1";"Базофилы_E2";"Эозинофилы_E2";"Гемоглобин_E2";"Эритроциты_E2" +"Группа 1";"31";"Женский";"174";"A (II)";"0,4222";"0,6465";"10,6842";"4,2573";"0,8264";"1,6613";"11,4051";"6,5728" +"Группа 1";"28";"Женский";"157";"A (II)";"0,3270";"4,9742";"9,6169";"3,8813";"0,7312";"5,9890";"10,3378";"6,1968" +"Группа 1";"33";"Женский";"166";NA;"0,7994";"3,3875";"10,1628";"5,0607";"1,2036";"4,4023";"10,8837";"7,3762" +"Группа 1";"26";"Женский";"168";"O (I)";"0,0237";"4,5403";"10,6391";"3,8083";"0,4279";"5,5551";"11,3600";"6,1238" +"Группа 1";"33";"Женский";"170";"A (II)";"0,6636";"3,3159";"12,2590";"3,0321";"1,0678";"4,3307";"12,9799";"5,3476" +"Группа 1";"28";"Мужской";"172";"B (III)";"0,4810";"2,7863";"12,3529";"4,7917";"0,8852";"3,8011";"13,0738";"7,1072" +"Группа 1";"27";"Мужской";"157";"A (II)";"0,8899";"2,3432";"11,2656";"3,3619";"1,2941";"3,3580";"11,9865";"5,6774" +"Группа 1";"31";"Мужской";"174";NA;"0,8576";"3,9788";"14,8948";"4,4598";"1,2618";"4,9936";"15,6157";"6,7753" +"Группа 1";"23";"Женский";"175";"A (II)";"0,3832";"3,3896";"15,6802";"4,4339";"0,7874";"4,4044";"16,4011";"6,7494" +"Группа 1";"29";"Женский";"172";"A (II)";"0,2812";"7,9352";"12,9084";"4,3275";"0,6854";"8,9500";"13,6293";"6,6430" +"Группа 1";"32";"Женский";"165";"A (II)";"0,8032";"2,4649";"10,1162";"3,4207";"1,2074";"3,4797";"10,8371";"5,7362" +"Группа 1";"33";"Мужской";"171";"B (III)";"0,7606";"2,8023";"11,0011";"4,3114";"1,1648";"3,8171";"11,7220";"6,6269" +"Группа 1";"30";"Женский";"176";NA;"-0,2188";"1,2468";"12,0861";"3,6621";"0,1854";"2,2616";"12,8070";"5,9776" +"Группа 1";"28";"Женский";"165";"O (I)";"0,5170";"8,1285";"11,4946";"2,8699";"0,9212";"9,1433";"12,2155";"5,1854" +"Группа 1";"25";"Женский";"170";"B (III)";"0,9893";"0,5132";"14,4936";"4,3594";"1,3935";"1,5280";"15,2145";"6,6749" +"Группа 1";"38";"Женский";"167";NA;"0,8990";"2,6541";"10,6878";"4,9044";"1,3032";"3,6689";"11,4087";"7,2199" +"Группа 1";"32";"Мужской";"177";"B (III)";"0,3413";"0,8715";"16,0903";"4,1925";"0,7455";"1,8863";"16,8112";"6,5080" +"Группа 1";"27";"Женский";"167";"B (III)";"0,4083";"3,7789";"13,2827";"4,5453";"0,8125";"4,7937";"14,0036";"6,8608" +"Группа 1";"28";"Женский";"169";"O (I)";"0,3009";"2,3743";"11,5597";"3,1849";"0,7051";"3,3891";"12,2806";"5,5004" +"Группа 1";"27";"Мужской";"158";"B (III)";"0,4160";"3,7980";"13,4759";"5,0699";"0,8202";"4,8128";"14,1968";"7,3854" +"Группа 1";"28";"Женский";"162";"O (I)";"0,8340";"2,5866";"12,3530";"3,7413";"1,2382";"3,6014";"13,0739";"6,0568" +"Группа 1";"31";"Женский";"164";"A (II)";"0,8936";"4,3898";"12,1520";"3,7300";"1,2978";"5,4046";"12,8729";"6,0455" +"Группа 1";"26";"Мужской";"171";NA;"0,8364";"5,0805";"8,6038";"4,6658";"1,2406";"6,0953";"9,3247";"6,9813" +"Группа 1";"34";"Женский";"173";NA;"0,8969";"4,5769";"14,0891";"3,7455";"1,3011";"5,5917";"14,8100";"6,0610" +"Группа 1";"27";"Мужской";"169";"O (I)";"0,5617";"5,6353";"11,1436";"3,8355";"0,9659";"6,6501";"11,8645";"6,1510" +"Группа 1";"31";"Женский";"173";"B (III)";"0,8466";"5,8133";"16,2315";"4,5226";"1,2508";"6,8281";"16,9524";"6,8381" +"Группа 1";"21";"Мужской";"156";"A (II)";"0,7375";"3,6625";"10,9569";"3,5251";"1,1417";"4,6773";"11,6778";"5,8406" +"Группа 1";"28";"Мужской";"164";NA;"0,8984";"0,2688";"13,7583";"3,9492";"1,3026";"1,2836";"14,4792";"6,2647" +"Группа 1";"27";"Женский";"168";"A (II)";"-0,0391";"1,6700";"10,4017";"3,6078";"0,3651";"2,6848";"11,1226";"5,9233" +"Группа 1";"33";"Мужской";"170";"O (I)";"-0,2002";"2,1515";"9,8202";"5,7281";"0,2040";"3,1663";"10,5411";"8,0436" +"Группа 1";"35";"Мужской";"155";"A (II)";"0,3337";"3,4448";"12,1903";"4,4991";"0,7379";"4,4596";"12,9112";"6,8146" +"Группа 1";"25";"Мужской";"175";NA;"0,2541";"3,8754";"15,2743";"4,7965";"0,6583";"4,8902";"15,9952";"7,1120" +"Группа 1";"36";"Женский";"169";"O (I)";"0,6489";"2,2938";"9,1329";"4,8499";"1,0531";"3,3086";"9,8538";"7,1654" +"Группа 1";"23";"Женский";"166";"O (I)";"0,4381";"2,5826";"11,1547";"4,4297";"0,8423";"3,5974";"11,8756";"6,7452" +"Группа 1";"32";"Женский";"162";"B (III)";"1,3054";"2,9359";"13,2145";"3,7860";"1,7096";"3,9507";"13,9354";"6,1015" +"Группа 1";"28";"Мужской";"165";"O (I)";"0,5758";"3,1627";"10,9963";"4,1499";"0,9800";"4,1775";"11,7172";"6,4654" +"Группа 1";"32";"Женский";"170";"B (III)";"0,2684";"1,8568";"11,2402";"3,3907";"0,6726";"2,8716";"11,9611";"5,7062" +"Группа 1";"31";"Женский";"171";"A (II)";"0,4208";"4,4054";"5,3523";"4,0110";"0,8250";"5,4202";"6,0732";"6,3265" +"Группа 1";"31";"Женский";"181";"B (III)";"0,1761";"3,0373";"9,5050";"4,7135";"0,5803";"4,0521";"10,2259";"7,0290" +"Группа 1";"25";"Женский";"179";"AB (IV)";"0,3180";"1,8673";"11,4646";"2,8206";"0,7222";"2,8821";"12,1855";"5,1361" +"Группа 1";"30";"Мужской";"156";"AB (IV)";"0,0509";"0,3804";"13,3238";"3,7554";"0,4551";"1,3952";"14,0447";"6,0709" +"Группа 1";"26";"Женский";"172";"AB (IV)";"0,4853";"3,3438";"10,5516";"4,4054";"0,8895";"4,3586";"11,2725";"6,7209" +"Группа 1";"33";"Женский";"164";"A (II)";"1,5915";"5,0897";"9,7669";"4,1358";"1,9957";"6,1045";"10,4878";"6,4513" +"Группа 1";"34";"Женский";"164";"A (II)";"0,3361";"4,2492";"12,4213";"4,2117";"0,7403";"5,2640";"13,1422";"6,5272" +"Группа 1";"24";"Женский";"163";NA;"0,2666";"2,3360";"15,1213";"4,7835";"0,6708";"3,3508";"15,8422";"7,0990" +"Группа 1";"25";"Женский";"171";"B (III)";"1,4540";"3,4946";"11,9013";"4,6613";"1,8582";"4,5094";"12,6222";"6,9768" +"Группа 1";"23";"Мужской";"162";"AB (IV)";"0,7981";"2,1393";"14,1017";"2,8917";"1,2023";"3,1541";"14,8226";"5,2072" +"Группа 1";"35";"Женский";"171";"A (II)";"0,3588";"5,0382";"10,6129";"4,4047";"0,7630";"6,0530";"11,3338";"6,7202" +"Группа 1";"29";"Мужской";"175";"O (I)";"0,8537";"-0,3005";"13,2050";"5,2975";"1,2579";"0,7143";"13,9259";"7,6130" +"Группа 1";"30";"Мужской";"171";"A (II)";"0,6650";"1,5940";"12,6169";"5,4316";"1,0692";"2,6088";"13,3378";"7,7471" +"Группа 2";"37";"Мужской";"165";"AB (IV)";"0,8954";"5,1303";"13,5317";"2,9260";"1,2996";"6,1451";"14,2526";"5,2415" +"Группа 2";"25";"Женский";"168";"O (I)";"1,3261";"6,8981";"13,2712";"4,0185";"1,7303";"7,9129";"13,9921";"6,3340" +"Группа 2";"32";"Женский";"159";"A (II)";"-0,0283";"4,0341";"8,8472";"3,5037";"0,3759";"5,0489";"9,5681";"5,8192" +"Группа 2";"35";"Мужской";"164";"AB (IV)";"0,8283";"7,0987";"10,1555";"3,9505";"1,2325";"8,1135";"10,8764";"6,2660" +"Группа 2";"29";"Мужской";"170";"O (I)";"0,4120";"6,0201";"9,6631";"4,0911";"0,8162";"7,0349";"10,3840";"6,4066" +"Группа 2";"34";"Мужской";"169";"B (III)";"0,3367";"3,6771";"11,9647";"5,2631";"0,7409";"4,6919";"12,6856";"7,5786" +"Группа 2";"34";"Мужской";"161";"A (II)";"0,7744";"4,4050";"11,9282";"3,2528";"1,1786";"5,4198";"12,6491";"5,5683" +"Группа 2";"27";"Женский";"167";NA;"0,1906";"3,8312";"11,2700";"5,0763";"0,5948";"4,8460";"11,9909";"7,3918" +"Группа 2";"34";"Женский";"175";"AB (IV)";"0,4139";"-1,0480";"10,5656";"3,9456";"0,8181";"-0,0332";"11,2865";"6,2611" +"Группа 2";"30";"Мужской";"167";"A (II)";"0,8407";"1,3026";"15,1292";"3,7485";"1,2449";"2,3174";"15,8501";"6,0640" +"Группа 2";"33";"Женский";"162";"A (II)";"1,0976";"6,3401";"10,9379";"4,3332";"1,5018";"7,3549";"11,6588";"6,6487" +"Группа 2";"26";"Мужской";"164";"O (I)";"0,8849";"1,4690";"12,1955";"4,9171";"1,2891";"2,4838";"12,9164";"7,2326" +"Группа 2";"28";"Мужской";"165";"A (II)";"1,7186";"5,9387";"11,2181";"4,2957";"2,1228";"6,9535";"11,9390";"6,6112" +"Группа 2";"35";"Мужской";"172";"O (I)";"1,2805";"7,0429";"12,3226";"4,0218";"1,6847";"8,0577";"13,0435";"6,3373" +"Группа 2";"22";"Женский";"161";NA;"0,9704";"6,2395";"10,6715";"4,2513";"1,3746";"7,2543";"11,3924";"6,5668" +"Группа 2";"34";"Мужской";"171";"A (II)";"1,1937";"2,0692";"11,7092";"3,3324";"1,5979";"3,0840";"12,4301";"5,6479" +"Группа 2";"27";"Мужской";"176";"A (II)";"0,6806";"3,4455";"10,4657";"4,7750";"1,0848";"4,4603";"11,1866";"7,0905" +"Группа 2";"32";"Женский";"159";"O (I)";"0,5602";"1,6435";"13,3411";"4,1875";"0,9644";"2,6583";"14,0620";"6,5030" +"Группа 2";"31";"Женский";"168";"A (II)";"0,7827";"3,9147";"13,1647";"4,7969";"1,1869";"4,9295";"13,8856";"7,1124" +"Группа 2";"31";"Мужской";"168";"B (III)";"0,9249";"4,7131";"11,0108";"3,2465";"1,3291";"5,7279";"11,7317";"5,5620" +"Группа 2";"33";"Мужской";"170";"B (III)";"1,4613";"7,2709";"11,7787";"4,0559";"1,8655";"8,2857";"12,4996";"6,3714" +"Группа 2";"30";"Женский";"165";"A (II)";"0,2669";"6,4108";"14,4411";"4,2103";"0,6711";"7,4256";"15,1620";"6,5258" +"Группа 2";"28";"Мужской";"174";"A (II)";"0,7950";"2,6174";"10,9779";"3,5962";"1,1992";"3,6322";"11,6988";"5,9117" +"Группа 2";"29";"Мужской";"171";"A (II)";"0,4820";"4,9124";"10,0890";"3,2071";"0,8862";"5,9272";"10,8099";"5,5226" +"Группа 2";"29";"Женский";"166";"O (I)";"0,6358";"4,7582";"11,3264";"3,5469";"1,0400";"5,7730";"12,0473";"5,8624" +"Группа 2";"21";"Мужской";"167";"O (I)";"0,4371";"2,5971";"14,2052";"4,3911";"0,8413";"3,6119";"14,9261";"6,7066" +"Группа 2";"29";"Мужской";"164";"O (I)";"0,6036";"6,0198";"13,3540";"4,8232";"1,0078";"7,0346";"14,0749";"7,1387" +"Группа 2";"33";"Женский";"159";"O (I)";"0,6529";"4,3756";"12,8750";"4,7547";"1,0571";"5,3904";"13,5959";"7,0702" +"Группа 2";"42";"Женский";"161";NA;"0,8271";"4,9020";"10,9604";"4,7991";"1,2313";"5,9168";"11,6813";"7,1146" +"Группа 2";"37";"Мужской";"160";"A (II)";"0,3053";"4,7937";"10,9401";"3,2195";"0,7095";"5,8085";"11,6610";"5,5350" +"Группа 2";"38";"Мужской";"177";"O (I)";"0,2841";"4,5635";"10,3758";"5,1561";"0,6883";"5,5783";"11,0967";"7,4716" +"Группа 2";"32";"Мужской";"160";"A (II)";"0,6112";"-0,6534";"11,9738";"3,4066";"1,0154";"0,3614";"12,6947";"5,7221" +"Группа 2";"28";"Мужской";"166";"A (II)";"0,6741";"3,8194";"9,8513";"3,0476";"1,0783";"4,8342";"10,5722";"5,3631" +"Группа 2";"34";"Мужской";"163";NA;"0,7178";"6,2474";"12,2265";"4,0731";"1,1220";"7,2622";"12,9474";"6,3886" +"Группа 2";"35";"Женский";"177";"A (II)";"0,7161";"6,1906";"9,9169";"2,8447";"1,1203";"7,2054";"10,6378";"5,1602" +"Группа 2";"29";"Женский";"176";"O (I)";"1,1057";"1,4231";"13,8564";"4,1773";"1,5099";"2,4379";"14,5773";"6,4928" +"Группа 2";"33";"Мужской";"170";"A (II)";"0,4425";"5,8075";"10,7608";"5,2198";"0,8467";"6,8223";"11,4817";"7,5353" +"Группа 2";"32";"Мужской";"174";NA;"0,9519";"7,4574";"11,4253";"3,6331";"1,3561";"8,4722";"12,1462";"5,9486" +"Группа 2";"33";"Женский";"161";"B (III)";"1,0887";"3,5337";"10,8088";"3,5177";"1,4929";"4,5485";"11,5297";"5,8332" +"Группа 2";"32";"Женский";"171";"O (I)";"0,5839";"2,5204";"13,1545";"4,0298";"0,9881";"3,5352";"13,8754";"6,3453" +"Группа 2";"28";"Мужской";"164";NA;"1,0915";"0,1390";"11,7136";"4,5780";"1,4957";"1,1538";"12,4345";"6,8935" +"Группа 2";"25";"Мужской";"176";"A (II)";"0,4885";"1,3760";"13,0178";"4,0390";"0,8927";"2,3908";"13,7387";"6,3545" +"Группа 2";"30";"Женский";"173";"O (I)";"0,1545";"4,3131";"12,9821";"5,1128";"0,5587";"5,3279";"13,7030";"7,4283" +"Группа 2";"32";"Женский";"176";"B (III)";"0,8272";"-1,2272";"10,2154";"5,0766";"1,2314";"-0,2124";"10,9363";"7,3921" +"Группа 2";"35";"Женский";"169";"A (II)";"1,3627";"5,9156";"11,9732";"3,5125";"1,7669";"6,9304";"12,6941";"5,8280" +"Группа 2";"33";"Мужской";"159";"AB (IV)";"0,6324";"5,7865";"10,2755";"3,6352";"1,0366";"6,8013";"10,9964";"5,9507" +"Группа 2";"33";"Мужской";"167";"O (I)";"0,5179";"7,4466";"13,2910";"3,8014";"0,9221";"8,4614";"14,0119";"6,1169" +"Группа 2";"30";"Мужской";"164";NA;"0,4240";"8,4344";"10,8290";"3,8113";"0,8282";"9,4492";"11,5499";"6,1268" +"Группа 2";"34";"Женский";"168";"O (I)";"0,9505";"0,8028";"13,4033";"3,5868";"1,3547";"1,8176";"14,1242";"5,9023" +"Группа 2";"30";"Женский";"169";NA;"0,7031";"5,3706";"12,2419";"3,2039";"1,1073";"6,3854";"12,9628";"5,5194" diff --git a/course-project/starter/data/data_excel.xlsx b/course-project/starter/data/data_excel.xlsx new file mode 100644 index 0000000..9b828ec Binary files /dev/null and b/course-project/starter/data/data_excel.xlsx differ diff --git a/course-project/starter/data/data_rds.rds b/course-project/starter/data/data_rds.rds new file mode 100644 index 0000000..92bbacb Binary files /dev/null and b/course-project/starter/data/data_rds.rds differ diff --git a/course-project/starter/data/data_tsv.tsv b/course-project/starter/data/data_tsv.tsv new file mode 100644 index 0000000..cdc3217 --- /dev/null +++ b/course-project/starter/data/data_tsv.tsv @@ -0,0 +1,101 @@ +Группа Возраст Пол Рост Группа крови Базофилы_E1 Эозинофилы_E1 Гемоглобин_E1 Эритроциты_E1 Базофилы_E2 Эозинофилы_E2 Гемоглобин_E2 Эритроциты_E2 +Группа 1 31 Женский 174 A (II) 0.4222 0.6465 10.6842 4.2573 0.8264 1.6613 11.4051 6.5728 +Группа 1 28 Женский 157 A (II) 0.327 4.9742 9.6169 3.8813 0.7312 5.989 10.3378 6.1968 +Группа 1 33 Женский 166 NA 0.7994 3.3875 10.1628 5.0607 1.2036 4.4023 10.8837 7.3762 +Группа 1 26 Женский 168 O (I) 0.0237 4.5403 10.6391 3.8083 0.4279 5.5551 11.36 6.1238 +Группа 1 33 Женский 170 A (II) 0.6636 3.3159 12.259 3.0321 1.0678 4.3307 12.9799 5.3476 +Группа 1 28 Мужской 172 B (III) 0.481 2.7863 12.3529 4.7917 0.8852 3.8011 13.0738 7.1072 +Группа 1 27 Мужской 157 A (II) 0.8899 2.3432 11.2656 3.3619 1.2941 3.358 11.9865 5.6774 +Группа 1 31 Мужской 174 NA 0.8576 3.9788 14.8948 4.4598 1.2618 4.9936 15.6157 6.7753 +Группа 1 23 Женский 175 A (II) 0.3832 3.3896 15.6802 4.4339 0.7874 4.4044 16.4011 6.7494 +Группа 1 29 Женский 172 A (II) 0.2812 7.9352 12.9084 4.3275 0.6854 8.95 13.6293 6.643 +Группа 1 32 Женский 165 A (II) 0.8032 2.4649 10.1162 3.4207 1.2074 3.4797 10.8371 5.7362 +Группа 1 33 Мужской 171 B (III) 0.7606 2.8023 11.0011 4.3114 1.1648 3.8171 11.722 6.6269 +Группа 1 30 Женский 176 NA -0.2188 1.2468 12.0861 3.6621 0.1854 2.2616 12.807 5.9776 +Группа 1 28 Женский 165 O (I) 0.517 8.1285 11.4946 2.8699 0.9212 9.1433 12.2155 5.1854 +Группа 1 25 Женский 170 B (III) 0.9893 0.5132 14.4936 4.3594 1.3935 1.528 15.2145 6.6749 +Группа 1 38 Женский 167 NA 0.899 2.6541 10.6878 4.9044 1.3032 3.6689 11.4087 7.2199 +Группа 1 32 Мужской 177 B (III) 0.3413 0.8715 16.0903 4.1925 0.7455 1.8863 16.8112 6.508 +Группа 1 27 Женский 167 B (III) 0.4083 3.7789 13.2827 4.5453 0.8125 4.7937 14.0036 6.8608 +Группа 1 28 Женский 169 O (I) 0.3009 2.3743 11.5597 3.1849 0.7051 3.3891 12.2806 5.5004 +Группа 1 27 Мужской 158 B (III) 0.416 3.798 13.4759 5.0699 0.8202 4.8128 14.1968 7.3854 +Группа 1 28 Женский 162 O (I) 0.834 2.5866 12.353 3.7413 1.2382 3.6014 13.0739 6.0568 +Группа 1 31 Женский 164 A (II) 0.8936 4.3898 12.152 3.73 1.2978 5.4046 12.8729 6.0455 +Группа 1 26 Мужской 171 NA 0.8364 5.0805 8.6038 4.6658 1.2406 6.0953 9.3247 6.9813 +Группа 1 34 Женский 173 NA 0.8969 4.5769 14.0891 3.7455 1.3011 5.5917 14.81 6.061 +Группа 1 27 Мужской 169 O (I) 0.5617 5.6353 11.1436 3.8355 0.9659 6.6501 11.8645 6.151 +Группа 1 31 Женский 173 B (III) 0.8466 5.8133 16.2315 4.5226 1.2508 6.8281 16.9524 6.8381 +Группа 1 21 Мужской 156 A (II) 0.7375 3.6625 10.9569 3.5251 1.1417 4.6773 11.6778 5.8406 +Группа 1 28 Мужской 164 NA 0.8984 0.2688 13.7583 3.9492 1.3026 1.2836 14.4792 6.2647 +Группа 1 27 Женский 168 A (II) -0.0391 1.67 10.4017 3.6078 0.3651 2.6848 11.1226 5.9233 +Группа 1 33 Мужской 170 O (I) -0.2002 2.1515 9.8202 5.7281 0.204 3.1663 10.5411 8.0436 +Группа 1 35 Мужской 155 A (II) 0.3337 3.4448 12.1903 4.4991 0.7379 4.4596 12.9112 6.8146 +Группа 1 25 Мужской 175 NA 0.2541 3.8754 15.2743 4.7965 0.6583 4.8902 15.9952 7.112 +Группа 1 36 Женский 169 O (I) 0.6489 2.2938 9.1329 4.8499 1.0531 3.3086 9.8538 7.1654 +Группа 1 23 Женский 166 O (I) 0.4381 2.5826 11.1547 4.4297 0.8423 3.5974 11.8756 6.7452 +Группа 1 32 Женский 162 B (III) 1.3054 2.9359 13.2145 3.786 1.7096 3.9507 13.9354 6.1015 +Группа 1 28 Мужской 165 O (I) 0.5758 3.1627 10.9963 4.1499 0.98 4.1775 11.7172 6.4654 +Группа 1 32 Женский 170 B (III) 0.2684 1.8568 11.2402 3.3907 0.6726 2.8716 11.9611 5.7062 +Группа 1 31 Женский 171 A (II) 0.4208 4.4054 5.3523 4.011 0.825 5.4202 6.0732 6.3265 +Группа 1 31 Женский 181 B (III) 0.1761 3.0373 9.505 4.7135 0.5803 4.0521 10.2259 7.029 +Группа 1 25 Женский 179 AB (IV) 0.318 1.8673 11.4646 2.8206 0.7222 2.8821 12.1855 5.1361 +Группа 1 30 Мужской 156 AB (IV) 0.0509 0.3804 13.3238 3.7554 0.4551 1.3952 14.0447 6.0709 +Группа 1 26 Женский 172 AB (IV) 0.4853 3.3438 10.5516 4.4054 0.8895 4.3586 11.2725 6.7209 +Группа 1 33 Женский 164 A (II) 1.5915 5.0897 9.7669 4.1358 1.9957 6.1045 10.4878 6.4513 +Группа 1 34 Женский 164 A (II) 0.3361 4.2492 12.4213 4.2117000000000004 0.7403 5.264 13.1422 6.5272 +Группа 1 24 Женский 163 NA 0.2666 2.336 15.1213 4.7835 0.6708 3.3508 15.8422 7.099 +Группа 1 25 Женский 171 B (III) 1.454 3.4946 11.9013 4.6613 1.8582 4.5094 12.6222 6.9768 +Группа 1 23 Мужской 162 AB (IV) 0.7981 2.1393 14.1017 2.8917 1.2023 3.1541 14.8226 5.2072 +Группа 1 35 Женский 171 A (II) 0.3588 5.0382 10.6129 4.4047 0.763 6.053 11.3338 6.7202 +Группа 1 29 Мужской 175 O (I) 0.8537 -0.3005 13.205 5.2975 1.2579 0.7143 13.9259 7.613 +Группа 1 30 Мужской 171 A (II) 0.665 1.594 12.6169 5.4316 1.0692 2.6088 13.3378 7.7471 +Группа 2 37 Мужской 165 AB (IV) 0.8954 5.1303 13.5317 2.926 1.2996 6.1451 14.2526 5.2415 +Группа 2 25 Женский 168 O (I) 1.3261 6.8981 13.2712 4.0185 1.7303 7.9129 13.9921 6.334 +Группа 2 32 Женский 159 A (II) -0.0283 4.0341 8.8472 3.5037 0.3759 5.0489 9.5681 5.8192 +Группа 2 35 Мужской 164 AB (IV) 0.8283 7.0987 10.1555 3.9505 1.2325 8.1135 10.8764 6.266 +Группа 2 29 Мужской 170 O (I) 0.412 6.0201 9.6631 4.0911 0.8162 7.0349 10.384 6.4066 +Группа 2 34 Мужской 169 B (III) 0.3367 3.6771 11.9647 5.2631 0.7409 4.6919 12.6856 7.5786 +Группа 2 34 Мужской 161 A (II) 0.7744 4.405 11.9282 3.2528 1.1786 5.4198 12.6491 5.5683 +Группа 2 27 Женский 167 NA 0.1906 3.8312 11.27 5.0763 0.5948 4.846 11.9909 7.3918 +Группа 2 34 Женский 175 AB (IV) 0.4139 -1.048 10.5656 3.9456 0.8181 -0.0332 11.2865 6.2611 +Группа 2 30 Мужской 167 A (II) 0.8407 1.3026 15.1292 3.7485 1.2449 2.3174 15.8501 6.064 +Группа 2 33 Женский 162 A (II) 1.0976 6.3401 10.9379 4.3332 1.5018 7.3549 11.6588 6.6487 +Группа 2 26 Мужской 164 O (I) 0.8849 1.469 12.1955 4.9171 1.2891 2.4838 12.9164 7.2326 +Группа 2 28 Мужской 165 A (II) 1.7186 5.9387 11.2181 4.2957 2.1228 6.9535 11.939 6.6112 +Группа 2 35 Мужской 172 O (I) 1.2805 7.0429 12.3226 4.0218 1.6847 8.0577 13.0435 6.3373 +Группа 2 22 Женский 161 NA 0.9704 6.2395 10.6715 4.2513 1.3746 7.2543 11.3924 6.5668 +Группа 2 34 Мужской 171 A (II) 1.1937 2.0692 11.7092 3.3324 1.5979 3.084 12.4301 5.6479 +Группа 2 27 Мужской 176 A (II) 0.6806 3.4455 10.4657 4.775 1.0848 4.4603 11.1866 7.0905 +Группа 2 32 Женский 159 O (I) 0.5602 1.6435 13.3411 4.1875 0.9644 2.6583 14.062 6.503 +Группа 2 31 Женский 168 A (II) 0.7827 3.9147 13.1647 4.7969 1.1869 4.9295 13.8856 7.1124 +Группа 2 31 Мужской 168 B (III) 0.92490000000000006 4.7131 11.0108 3.2465 1.3291 5.7279 11.7317 5.562 +Группа 2 33 Мужской 170 B (III) 1.4613 7.2709 11.7787 4.0559 1.8655 8.2857 12.4996 6.3714 +Группа 2 30 Женский 165 A (II) 0.2669 6.4108 14.4411 4.2103 0.6711 7.4256 15.162 6.5258 +Группа 2 28 Мужской 174 A (II) 0.795 2.6174 10.9779 3.5962 1.1992 3.6322 11.6988 5.9117 +Группа 2 29 Мужской 171 A (II) 0.482 4.9124 10.089 3.2071 0.8862 5.9272 10.8099 5.5226 +Группа 2 29 Женский 166 O (I) 0.6358 4.7582 11.3264 3.5469 1.04 5.773 12.0473 5.8624 +Группа 2 21 Мужской 167 O (I) 0.4371 2.5971 14.2052 4.3911 0.8413 3.6119 14.9261 6.7066 +Группа 2 29 Мужской 164 O (I) 0.6036 6.0198 13.354 4.8232 1.0078 7.0346 14.0749 7.1387 +Группа 2 33 Женский 159 O (I) 0.6529 4.3756 12.875 4.7547 1.0571 5.3904 13.5959 7.0702 +Группа 2 42 Женский 161 NA 0.8271 4.902 10.9604 4.7991 1.2313 5.9168 11.6813 7.1146 +Группа 2 37 Мужской 160 A (II) 0.3053 4.7937 10.9401 3.2195 0.7095 5.8085 11.661 5.535 +Группа 2 38 Мужской 177 O (I) 0.2841 4.5635 10.3758 5.1561 0.6883 5.5783 11.0967 7.4716 +Группа 2 32 Мужской 160 A (II) 0.6112 -0.6534 11.9738 3.4066 1.0154 0.3614 12.6947 5.7221 +Группа 2 28 Мужской 166 A (II) 0.6741 3.8194 9.8513 3.0476 1.0783 4.8342 10.5722 5.3631 +Группа 2 34 Мужской 163 NA 0.7178 6.2474 12.2265 4.0731 1.122 7.2622 12.9474 6.3886 +Группа 2 35 Женский 177 A (II) 0.7161 6.1906 9.9169 2.8447 1.1203 7.2054 10.6378 5.1602 +Группа 2 29 Женский 176 O (I) 1.1057 1.4231 13.8564 4.1773 1.5099 2.4379 14.5773 6.4928 +Группа 2 33 Мужской 170 A (II) 0.4425 5.8075 10.7608 5.2198 0.8467 6.8223 11.4817 7.5353 +Группа 2 32 Мужской 174 NA 0.9519 7.4574 11.4253 3.6331 1.3561 8.4722 12.1462 5.9486 +Группа 2 33 Женский 161 B (III) 1.0887 3.5337 10.8088 3.5177 1.4929 4.5485 11.5297 5.8332 +Группа 2 32 Женский 171 O (I) 0.5839 2.5204 13.1545 4.0298 0.9881 3.5352 13.8754 6.3453 +Группа 2 28 Мужской 164 NA 1.0915 0.139 11.7136 4.578 1.4957 1.1538 12.4345 6.8935 +Группа 2 25 Мужской 176 A (II) 0.4885 1.376 13.0178 4.039 0.8927 2.3908 13.7387 6.3545 +Группа 2 30 Женский 173 O (I) 0.1545 4.3131 12.9821 5.1128 0.5587 5.3279 13.703 7.4283 +Группа 2 32 Женский 176 B (III) 0.8272 -1.2272 10.2154 5.0766 1.2314 -0.2124 10.9363 7.3921 +Группа 2 35 Женский 169 A (II) 1.3627 5.9156 11.9732 3.5125 1.7669 6.9304 12.6941 5.828 +Группа 2 33 Мужской 159 AB (IV) 0.6324 5.7865 10.2755 3.6352 1.0366 6.8013 10.9964 5.9507 +Группа 2 33 Мужской 167 O (I) 0.5179 7.4466 13.291 3.8014 0.9221 8.4614 14.0119 6.1169 +Группа 2 30 Мужской 164 NA 0.424 8.4344 10.829 3.8113 0.8282 9.4492 11.5499 6.1268 +Группа 2 34 Женский 168 O (I) 0.9505 0.8028 13.4033 3.5868 1.3547 1.8176 14.1242 5.9023 +Группа 2 30 Женский 169 NA 0.7031 5.3706 12.2419 3.2039 1.1073 6.3854 12.9628 5.5194 diff --git a/course-project/starter/data/penguins.csv b/course-project/starter/data/penguins.csv new file mode 100644 index 0000000..3a39afa --- /dev/null +++ b/course-project/starter/data/penguins.csv @@ -0,0 +1,345 @@ +"species","island","bill_len","bill_dep","flipper_len","body_mass","sex","year" +"Adelie","Torgersen",39.1,18.7,181,3750,"male",2007 +"Adelie","Torgersen",39.5,17.4,186,3800,"female",2007 +"Adelie","Torgersen",40.3,18,195,3250,"female",2007 +"Adelie","Torgersen",,,,,,2007 +"Adelie","Torgersen",36.7,19.3,193,3450,"female",2007 +"Adelie","Torgersen",39.3,20.6,190,3650,"male",2007 +"Adelie","Torgersen",38.9,17.8,181,3625,"female",2007 +"Adelie","Torgersen",39.2,19.6,195,4675,"male",2007 +"Adelie","Torgersen",34.1,18.1,193,3475,,2007 +"Adelie","Torgersen",42,20.2,190,4250,,2007 +"Adelie","Torgersen",37.8,17.1,186,3300,,2007 +"Adelie","Torgersen",37.8,17.3,180,3700,,2007 +"Adelie","Torgersen",41.1,17.6,182,3200,"female",2007 +"Adelie","Torgersen",38.6,21.2,191,3800,"male",2007 +"Adelie","Torgersen",34.6,21.1,198,4400,"male",2007 +"Adelie","Torgersen",36.6,17.8,185,3700,"female",2007 +"Adelie","Torgersen",38.7,19,195,3450,"female",2007 +"Adelie","Torgersen",42.5,20.7,197,4500,"male",2007 +"Adelie","Torgersen",34.4,18.4,184,3325,"female",2007 +"Adelie","Torgersen",46,21.5,194,4200,"male",2007 +"Adelie","Biscoe",37.8,18.3,174,3400,"female",2007 +"Adelie","Biscoe",37.7,18.7,180,3600,"male",2007 +"Adelie","Biscoe",35.9,19.2,189,3800,"female",2007 +"Adelie","Biscoe",38.2,18.1,185,3950,"male",2007 +"Adelie","Biscoe",38.8,17.2,180,3800,"male",2007 +"Adelie","Biscoe",35.3,18.9,187,3800,"female",2007 +"Adelie","Biscoe",40.6,18.6,183,3550,"male",2007 +"Adelie","Biscoe",40.5,17.9,187,3200,"female",2007 +"Adelie","Biscoe",37.9,18.6,172,3150,"female",2007 +"Adelie","Biscoe",40.5,18.9,180,3950,"male",2007 +"Adelie","Dream",39.5,16.7,178,3250,"female",2007 +"Adelie","Dream",37.2,18.1,178,3900,"male",2007 +"Adelie","Dream",39.5,17.8,188,3300,"female",2007 +"Adelie","Dream",40.9,18.9,184,3900,"male",2007 +"Adelie","Dream",36.4,17,195,3325,"female",2007 +"Adelie","Dream",39.2,21.1,196,4150,"male",2007 +"Adelie","Dream",38.8,20,190,3950,"male",2007 +"Adelie","Dream",42.2,18.5,180,3550,"female",2007 +"Adelie","Dream",37.6,19.3,181,3300,"female",2007 +"Adelie","Dream",39.8,19.1,184,4650,"male",2007 +"Adelie","Dream",36.5,18,182,3150,"female",2007 +"Adelie","Dream",40.8,18.4,195,3900,"male",2007 +"Adelie","Dream",36,18.5,186,3100,"female",2007 +"Adelie","Dream",44.1,19.7,196,4400,"male",2007 +"Adelie","Dream",37,16.9,185,3000,"female",2007 +"Adelie","Dream",39.6,18.8,190,4600,"male",2007 +"Adelie","Dream",41.1,19,182,3425,"male",2007 +"Adelie","Dream",37.5,18.9,179,2975,,2007 +"Adelie","Dream",36,17.9,190,3450,"female",2007 +"Adelie","Dream",42.3,21.2,191,4150,"male",2007 +"Adelie","Biscoe",39.6,17.7,186,3500,"female",2008 +"Adelie","Biscoe",40.1,18.9,188,4300,"male",2008 +"Adelie","Biscoe",35,17.9,190,3450,"female",2008 +"Adelie","Biscoe",42,19.5,200,4050,"male",2008 +"Adelie","Biscoe",34.5,18.1,187,2900,"female",2008 +"Adelie","Biscoe",41.4,18.6,191,3700,"male",2008 +"Adelie","Biscoe",39,17.5,186,3550,"female",2008 +"Adelie","Biscoe",40.6,18.8,193,3800,"male",2008 +"Adelie","Biscoe",36.5,16.6,181,2850,"female",2008 +"Adelie","Biscoe",37.6,19.1,194,3750,"male",2008 +"Adelie","Biscoe",35.7,16.9,185,3150,"female",2008 +"Adelie","Biscoe",41.3,21.1,195,4400,"male",2008 +"Adelie","Biscoe",37.6,17,185,3600,"female",2008 +"Adelie","Biscoe",41.1,18.2,192,4050,"male",2008 +"Adelie","Biscoe",36.4,17.1,184,2850,"female",2008 +"Adelie","Biscoe",41.6,18,192,3950,"male",2008 +"Adelie","Biscoe",35.5,16.2,195,3350,"female",2008 +"Adelie","Biscoe",41.1,19.1,188,4100,"male",2008 +"Adelie","Torgersen",35.9,16.6,190,3050,"female",2008 +"Adelie","Torgersen",41.8,19.4,198,4450,"male",2008 +"Adelie","Torgersen",33.5,19,190,3600,"female",2008 +"Adelie","Torgersen",39.7,18.4,190,3900,"male",2008 +"Adelie","Torgersen",39.6,17.2,196,3550,"female",2008 +"Adelie","Torgersen",45.8,18.9,197,4150,"male",2008 +"Adelie","Torgersen",35.5,17.5,190,3700,"female",2008 +"Adelie","Torgersen",42.8,18.5,195,4250,"male",2008 +"Adelie","Torgersen",40.9,16.8,191,3700,"female",2008 +"Adelie","Torgersen",37.2,19.4,184,3900,"male",2008 +"Adelie","Torgersen",36.2,16.1,187,3550,"female",2008 +"Adelie","Torgersen",42.1,19.1,195,4000,"male",2008 +"Adelie","Torgersen",34.6,17.2,189,3200,"female",2008 +"Adelie","Torgersen",42.9,17.6,196,4700,"male",2008 +"Adelie","Torgersen",36.7,18.8,187,3800,"female",2008 +"Adelie","Torgersen",35.1,19.4,193,4200,"male",2008 +"Adelie","Dream",37.3,17.8,191,3350,"female",2008 +"Adelie","Dream",41.3,20.3,194,3550,"male",2008 +"Adelie","Dream",36.3,19.5,190,3800,"male",2008 +"Adelie","Dream",36.9,18.6,189,3500,"female",2008 +"Adelie","Dream",38.3,19.2,189,3950,"male",2008 +"Adelie","Dream",38.9,18.8,190,3600,"female",2008 +"Adelie","Dream",35.7,18,202,3550,"female",2008 +"Adelie","Dream",41.1,18.1,205,4300,"male",2008 +"Adelie","Dream",34,17.1,185,3400,"female",2008 +"Adelie","Dream",39.6,18.1,186,4450,"male",2008 +"Adelie","Dream",36.2,17.3,187,3300,"female",2008 +"Adelie","Dream",40.8,18.9,208,4300,"male",2008 +"Adelie","Dream",38.1,18.6,190,3700,"female",2008 +"Adelie","Dream",40.3,18.5,196,4350,"male",2008 +"Adelie","Dream",33.1,16.1,178,2900,"female",2008 +"Adelie","Dream",43.2,18.5,192,4100,"male",2008 +"Adelie","Biscoe",35,17.9,192,3725,"female",2009 +"Adelie","Biscoe",41,20,203,4725,"male",2009 +"Adelie","Biscoe",37.7,16,183,3075,"female",2009 +"Adelie","Biscoe",37.8,20,190,4250,"male",2009 +"Adelie","Biscoe",37.9,18.6,193,2925,"female",2009 +"Adelie","Biscoe",39.7,18.9,184,3550,"male",2009 +"Adelie","Biscoe",38.6,17.2,199,3750,"female",2009 +"Adelie","Biscoe",38.2,20,190,3900,"male",2009 +"Adelie","Biscoe",38.1,17,181,3175,"female",2009 +"Adelie","Biscoe",43.2,19,197,4775,"male",2009 +"Adelie","Biscoe",38.1,16.5,198,3825,"female",2009 +"Adelie","Biscoe",45.6,20.3,191,4600,"male",2009 +"Adelie","Biscoe",39.7,17.7,193,3200,"female",2009 +"Adelie","Biscoe",42.2,19.5,197,4275,"male",2009 +"Adelie","Biscoe",39.6,20.7,191,3900,"female",2009 +"Adelie","Biscoe",42.7,18.3,196,4075,"male",2009 +"Adelie","Torgersen",38.6,17,188,2900,"female",2009 +"Adelie","Torgersen",37.3,20.5,199,3775,"male",2009 +"Adelie","Torgersen",35.7,17,189,3350,"female",2009 +"Adelie","Torgersen",41.1,18.6,189,3325,"male",2009 +"Adelie","Torgersen",36.2,17.2,187,3150,"female",2009 +"Adelie","Torgersen",37.7,19.8,198,3500,"male",2009 +"Adelie","Torgersen",40.2,17,176,3450,"female",2009 +"Adelie","Torgersen",41.4,18.5,202,3875,"male",2009 +"Adelie","Torgersen",35.2,15.9,186,3050,"female",2009 +"Adelie","Torgersen",40.6,19,199,4000,"male",2009 +"Adelie","Torgersen",38.8,17.6,191,3275,"female",2009 +"Adelie","Torgersen",41.5,18.3,195,4300,"male",2009 +"Adelie","Torgersen",39,17.1,191,3050,"female",2009 +"Adelie","Torgersen",44.1,18,210,4000,"male",2009 +"Adelie","Torgersen",38.5,17.9,190,3325,"female",2009 +"Adelie","Torgersen",43.1,19.2,197,3500,"male",2009 +"Adelie","Dream",36.8,18.5,193,3500,"female",2009 +"Adelie","Dream",37.5,18.5,199,4475,"male",2009 +"Adelie","Dream",38.1,17.6,187,3425,"female",2009 +"Adelie","Dream",41.1,17.5,190,3900,"male",2009 +"Adelie","Dream",35.6,17.5,191,3175,"female",2009 +"Adelie","Dream",40.2,20.1,200,3975,"male",2009 +"Adelie","Dream",37,16.5,185,3400,"female",2009 +"Adelie","Dream",39.7,17.9,193,4250,"male",2009 +"Adelie","Dream",40.2,17.1,193,3400,"female",2009 +"Adelie","Dream",40.6,17.2,187,3475,"male",2009 +"Adelie","Dream",32.1,15.5,188,3050,"female",2009 +"Adelie","Dream",40.7,17,190,3725,"male",2009 +"Adelie","Dream",37.3,16.8,192,3000,"female",2009 +"Adelie","Dream",39,18.7,185,3650,"male",2009 +"Adelie","Dream",39.2,18.6,190,4250,"male",2009 +"Adelie","Dream",36.6,18.4,184,3475,"female",2009 +"Adelie","Dream",36,17.8,195,3450,"female",2009 +"Adelie","Dream",37.8,18.1,193,3750,"male",2009 +"Adelie","Dream",36,17.1,187,3700,"female",2009 +"Adelie","Dream",41.5,18.5,201,4000,"male",2009 +"Gentoo","Biscoe",46.1,13.2,211,4500,"female",2007 +"Gentoo","Biscoe",50,16.3,230,5700,"male",2007 +"Gentoo","Biscoe",48.7,14.1,210,4450,"female",2007 +"Gentoo","Biscoe",50,15.2,218,5700,"male",2007 +"Gentoo","Biscoe",47.6,14.5,215,5400,"male",2007 +"Gentoo","Biscoe",46.5,13.5,210,4550,"female",2007 +"Gentoo","Biscoe",45.4,14.6,211,4800,"female",2007 +"Gentoo","Biscoe",46.7,15.3,219,5200,"male",2007 +"Gentoo","Biscoe",43.3,13.4,209,4400,"female",2007 +"Gentoo","Biscoe",46.8,15.4,215,5150,"male",2007 +"Gentoo","Biscoe",40.9,13.7,214,4650,"female",2007 +"Gentoo","Biscoe",49,16.1,216,5550,"male",2007 +"Gentoo","Biscoe",45.5,13.7,214,4650,"female",2007 +"Gentoo","Biscoe",48.4,14.6,213,5850,"male",2007 +"Gentoo","Biscoe",45.8,14.6,210,4200,"female",2007 +"Gentoo","Biscoe",49.3,15.7,217,5850,"male",2007 +"Gentoo","Biscoe",42,13.5,210,4150,"female",2007 +"Gentoo","Biscoe",49.2,15.2,221,6300,"male",2007 +"Gentoo","Biscoe",46.2,14.5,209,4800,"female",2007 +"Gentoo","Biscoe",48.7,15.1,222,5350,"male",2007 +"Gentoo","Biscoe",50.2,14.3,218,5700,"male",2007 +"Gentoo","Biscoe",45.1,14.5,215,5000,"female",2007 +"Gentoo","Biscoe",46.5,14.5,213,4400,"female",2007 +"Gentoo","Biscoe",46.3,15.8,215,5050,"male",2007 +"Gentoo","Biscoe",42.9,13.1,215,5000,"female",2007 +"Gentoo","Biscoe",46.1,15.1,215,5100,"male",2007 +"Gentoo","Biscoe",44.5,14.3,216,4100,,2007 +"Gentoo","Biscoe",47.8,15,215,5650,"male",2007 +"Gentoo","Biscoe",48.2,14.3,210,4600,"female",2007 +"Gentoo","Biscoe",50,15.3,220,5550,"male",2007 +"Gentoo","Biscoe",47.3,15.3,222,5250,"male",2007 +"Gentoo","Biscoe",42.8,14.2,209,4700,"female",2007 +"Gentoo","Biscoe",45.1,14.5,207,5050,"female",2007 +"Gentoo","Biscoe",59.6,17,230,6050,"male",2007 +"Gentoo","Biscoe",49.1,14.8,220,5150,"female",2008 +"Gentoo","Biscoe",48.4,16.3,220,5400,"male",2008 +"Gentoo","Biscoe",42.6,13.7,213,4950,"female",2008 +"Gentoo","Biscoe",44.4,17.3,219,5250,"male",2008 +"Gentoo","Biscoe",44,13.6,208,4350,"female",2008 +"Gentoo","Biscoe",48.7,15.7,208,5350,"male",2008 +"Gentoo","Biscoe",42.7,13.7,208,3950,"female",2008 +"Gentoo","Biscoe",49.6,16,225,5700,"male",2008 +"Gentoo","Biscoe",45.3,13.7,210,4300,"female",2008 +"Gentoo","Biscoe",49.6,15,216,4750,"male",2008 +"Gentoo","Biscoe",50.5,15.9,222,5550,"male",2008 +"Gentoo","Biscoe",43.6,13.9,217,4900,"female",2008 +"Gentoo","Biscoe",45.5,13.9,210,4200,"female",2008 +"Gentoo","Biscoe",50.5,15.9,225,5400,"male",2008 +"Gentoo","Biscoe",44.9,13.3,213,5100,"female",2008 +"Gentoo","Biscoe",45.2,15.8,215,5300,"male",2008 +"Gentoo","Biscoe",46.6,14.2,210,4850,"female",2008 +"Gentoo","Biscoe",48.5,14.1,220,5300,"male",2008 +"Gentoo","Biscoe",45.1,14.4,210,4400,"female",2008 +"Gentoo","Biscoe",50.1,15,225,5000,"male",2008 +"Gentoo","Biscoe",46.5,14.4,217,4900,"female",2008 +"Gentoo","Biscoe",45,15.4,220,5050,"male",2008 +"Gentoo","Biscoe",43.8,13.9,208,4300,"female",2008 +"Gentoo","Biscoe",45.5,15,220,5000,"male",2008 +"Gentoo","Biscoe",43.2,14.5,208,4450,"female",2008 +"Gentoo","Biscoe",50.4,15.3,224,5550,"male",2008 +"Gentoo","Biscoe",45.3,13.8,208,4200,"female",2008 +"Gentoo","Biscoe",46.2,14.9,221,5300,"male",2008 +"Gentoo","Biscoe",45.7,13.9,214,4400,"female",2008 +"Gentoo","Biscoe",54.3,15.7,231,5650,"male",2008 +"Gentoo","Biscoe",45.8,14.2,219,4700,"female",2008 +"Gentoo","Biscoe",49.8,16.8,230,5700,"male",2008 +"Gentoo","Biscoe",46.2,14.4,214,4650,,2008 +"Gentoo","Biscoe",49.5,16.2,229,5800,"male",2008 +"Gentoo","Biscoe",43.5,14.2,220,4700,"female",2008 +"Gentoo","Biscoe",50.7,15,223,5550,"male",2008 +"Gentoo","Biscoe",47.7,15,216,4750,"female",2008 +"Gentoo","Biscoe",46.4,15.6,221,5000,"male",2008 +"Gentoo","Biscoe",48.2,15.6,221,5100,"male",2008 +"Gentoo","Biscoe",46.5,14.8,217,5200,"female",2008 +"Gentoo","Biscoe",46.4,15,216,4700,"female",2008 +"Gentoo","Biscoe",48.6,16,230,5800,"male",2008 +"Gentoo","Biscoe",47.5,14.2,209,4600,"female",2008 +"Gentoo","Biscoe",51.1,16.3,220,6000,"male",2008 +"Gentoo","Biscoe",45.2,13.8,215,4750,"female",2008 +"Gentoo","Biscoe",45.2,16.4,223,5950,"male",2008 +"Gentoo","Biscoe",49.1,14.5,212,4625,"female",2009 +"Gentoo","Biscoe",52.5,15.6,221,5450,"male",2009 +"Gentoo","Biscoe",47.4,14.6,212,4725,"female",2009 +"Gentoo","Biscoe",50,15.9,224,5350,"male",2009 +"Gentoo","Biscoe",44.9,13.8,212,4750,"female",2009 +"Gentoo","Biscoe",50.8,17.3,228,5600,"male",2009 +"Gentoo","Biscoe",43.4,14.4,218,4600,"female",2009 +"Gentoo","Biscoe",51.3,14.2,218,5300,"male",2009 +"Gentoo","Biscoe",47.5,14,212,4875,"female",2009 +"Gentoo","Biscoe",52.1,17,230,5550,"male",2009 +"Gentoo","Biscoe",47.5,15,218,4950,"female",2009 +"Gentoo","Biscoe",52.2,17.1,228,5400,"male",2009 +"Gentoo","Biscoe",45.5,14.5,212,4750,"female",2009 +"Gentoo","Biscoe",49.5,16.1,224,5650,"male",2009 +"Gentoo","Biscoe",44.5,14.7,214,4850,"female",2009 +"Gentoo","Biscoe",50.8,15.7,226,5200,"male",2009 +"Gentoo","Biscoe",49.4,15.8,216,4925,"male",2009 +"Gentoo","Biscoe",46.9,14.6,222,4875,"female",2009 +"Gentoo","Biscoe",48.4,14.4,203,4625,"female",2009 +"Gentoo","Biscoe",51.1,16.5,225,5250,"male",2009 +"Gentoo","Biscoe",48.5,15,219,4850,"female",2009 +"Gentoo","Biscoe",55.9,17,228,5600,"male",2009 +"Gentoo","Biscoe",47.2,15.5,215,4975,"female",2009 +"Gentoo","Biscoe",49.1,15,228,5500,"male",2009 +"Gentoo","Biscoe",47.3,13.8,216,4725,,2009 +"Gentoo","Biscoe",46.8,16.1,215,5500,"male",2009 +"Gentoo","Biscoe",41.7,14.7,210,4700,"female",2009 +"Gentoo","Biscoe",53.4,15.8,219,5500,"male",2009 +"Gentoo","Biscoe",43.3,14,208,4575,"female",2009 +"Gentoo","Biscoe",48.1,15.1,209,5500,"male",2009 +"Gentoo","Biscoe",50.5,15.2,216,5000,"female",2009 +"Gentoo","Biscoe",49.8,15.9,229,5950,"male",2009 +"Gentoo","Biscoe",43.5,15.2,213,4650,"female",2009 +"Gentoo","Biscoe",51.5,16.3,230,5500,"male",2009 +"Gentoo","Biscoe",46.2,14.1,217,4375,"female",2009 +"Gentoo","Biscoe",55.1,16,230,5850,"male",2009 +"Gentoo","Biscoe",44.5,15.7,217,4875,,2009 +"Gentoo","Biscoe",48.8,16.2,222,6000,"male",2009 +"Gentoo","Biscoe",47.2,13.7,214,4925,"female",2009 +"Gentoo","Biscoe",,,,,,2009 +"Gentoo","Biscoe",46.8,14.3,215,4850,"female",2009 +"Gentoo","Biscoe",50.4,15.7,222,5750,"male",2009 +"Gentoo","Biscoe",45.2,14.8,212,5200,"female",2009 +"Gentoo","Biscoe",49.9,16.1,213,5400,"male",2009 +"Chinstrap","Dream",46.5,17.9,192,3500,"female",2007 +"Chinstrap","Dream",50,19.5,196,3900,"male",2007 +"Chinstrap","Dream",51.3,19.2,193,3650,"male",2007 +"Chinstrap","Dream",45.4,18.7,188,3525,"female",2007 +"Chinstrap","Dream",52.7,19.8,197,3725,"male",2007 +"Chinstrap","Dream",45.2,17.8,198,3950,"female",2007 +"Chinstrap","Dream",46.1,18.2,178,3250,"female",2007 +"Chinstrap","Dream",51.3,18.2,197,3750,"male",2007 +"Chinstrap","Dream",46,18.9,195,4150,"female",2007 +"Chinstrap","Dream",51.3,19.9,198,3700,"male",2007 +"Chinstrap","Dream",46.6,17.8,193,3800,"female",2007 +"Chinstrap","Dream",51.7,20.3,194,3775,"male",2007 +"Chinstrap","Dream",47,17.3,185,3700,"female",2007 +"Chinstrap","Dream",52,18.1,201,4050,"male",2007 +"Chinstrap","Dream",45.9,17.1,190,3575,"female",2007 +"Chinstrap","Dream",50.5,19.6,201,4050,"male",2007 +"Chinstrap","Dream",50.3,20,197,3300,"male",2007 +"Chinstrap","Dream",58,17.8,181,3700,"female",2007 +"Chinstrap","Dream",46.4,18.6,190,3450,"female",2007 +"Chinstrap","Dream",49.2,18.2,195,4400,"male",2007 +"Chinstrap","Dream",42.4,17.3,181,3600,"female",2007 +"Chinstrap","Dream",48.5,17.5,191,3400,"male",2007 +"Chinstrap","Dream",43.2,16.6,187,2900,"female",2007 +"Chinstrap","Dream",50.6,19.4,193,3800,"male",2007 +"Chinstrap","Dream",46.7,17.9,195,3300,"female",2007 +"Chinstrap","Dream",52,19,197,4150,"male",2007 +"Chinstrap","Dream",50.5,18.4,200,3400,"female",2008 +"Chinstrap","Dream",49.5,19,200,3800,"male",2008 +"Chinstrap","Dream",46.4,17.8,191,3700,"female",2008 +"Chinstrap","Dream",52.8,20,205,4550,"male",2008 +"Chinstrap","Dream",40.9,16.6,187,3200,"female",2008 +"Chinstrap","Dream",54.2,20.8,201,4300,"male",2008 +"Chinstrap","Dream",42.5,16.7,187,3350,"female",2008 +"Chinstrap","Dream",51,18.8,203,4100,"male",2008 +"Chinstrap","Dream",49.7,18.6,195,3600,"male",2008 +"Chinstrap","Dream",47.5,16.8,199,3900,"female",2008 +"Chinstrap","Dream",47.6,18.3,195,3850,"female",2008 +"Chinstrap","Dream",52,20.7,210,4800,"male",2008 +"Chinstrap","Dream",46.9,16.6,192,2700,"female",2008 +"Chinstrap","Dream",53.5,19.9,205,4500,"male",2008 +"Chinstrap","Dream",49,19.5,210,3950,"male",2008 +"Chinstrap","Dream",46.2,17.5,187,3650,"female",2008 +"Chinstrap","Dream",50.9,19.1,196,3550,"male",2008 +"Chinstrap","Dream",45.5,17,196,3500,"female",2008 +"Chinstrap","Dream",50.9,17.9,196,3675,"female",2009 +"Chinstrap","Dream",50.8,18.5,201,4450,"male",2009 +"Chinstrap","Dream",50.1,17.9,190,3400,"female",2009 +"Chinstrap","Dream",49,19.6,212,4300,"male",2009 +"Chinstrap","Dream",51.5,18.7,187,3250,"male",2009 +"Chinstrap","Dream",49.8,17.3,198,3675,"female",2009 +"Chinstrap","Dream",48.1,16.4,199,3325,"female",2009 +"Chinstrap","Dream",51.4,19,201,3950,"male",2009 +"Chinstrap","Dream",45.7,17.3,193,3600,"female",2009 +"Chinstrap","Dream",50.7,19.7,203,4050,"male",2009 +"Chinstrap","Dream",42.5,17.3,187,3350,"female",2009 +"Chinstrap","Dream",52.2,18.8,197,3450,"male",2009 +"Chinstrap","Dream",45.2,16.6,191,3250,"female",2009 +"Chinstrap","Dream",49.3,19.9,203,4050,"male",2009 +"Chinstrap","Dream",50.2,18.8,202,3800,"male",2009 +"Chinstrap","Dream",45.6,19.4,194,3525,"female",2009 +"Chinstrap","Dream",51.9,19.5,206,3950,"male",2009 +"Chinstrap","Dream",46.8,16.5,189,3650,"female",2009 +"Chinstrap","Dream",45.7,17,195,3650,"female",2009 +"Chinstrap","Dream",55.8,19.8,207,4000,"male",2009 +"Chinstrap","Dream",43.5,18.1,202,3400,"female",2009 +"Chinstrap","Dream",49.6,18.2,193,3775,"male",2009 +"Chinstrap","Dream",50.8,19,210,4100,"male",2009 +"Chinstrap","Dream",50.2,18.7,198,3775,"female",2009 diff --git a/course-project/starter/out/hist.png b/course-project/starter/out/hist.png new file mode 100644 index 0000000..9653909 Binary files /dev/null and b/course-project/starter/out/hist.png differ diff --git a/course-project/starter/penguins.R b/course-project/starter/penguins.R new file mode 100644 index 0000000..1f4561a --- /dev/null +++ b/course-project/starter/penguins.R @@ -0,0 +1,9 @@ +penguins <- read.csv("data/penguins.csv") +dream <- subset(penguins, island == "Dream") + +gigapeng <- max(dream$flipper_len) + +png("out/hist.png", width = 800, height = 600) +hist(dream$flipper_len) +dev.off() + diff --git a/course-project/starter/report.html b/course-project/starter/report.html new file mode 100644 index 0000000..c46c82c --- /dev/null +++ b/course-project/starter/report.html @@ -0,0 +1,2652 @@ + + + + + + + + + +Пингвины с острова Dream + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+

Пингвины с острова Dream

+
+ + + +
+ + + + +
+ + + +
+ + +

Данные собраны на трёх островах архипелага Палмера. Возьмём пингвинов с острова Dream.

+
+
penguins <- read.csv("data/penguins.csv")
+dream <- subset(penguins, island == "Dream")
+nrow(dream)
+
+
[1] 124
+
+
+

Самый длинный плавник:

+
+
gigapeng <- max(dream$flipper_len)
+gigapeng
+
+
[1] 212
+
+
+ +
+ + +
+ + + + + \ No newline at end of file diff --git a/course-project/starter/report.qmd b/course-project/starter/report.qmd new file mode 100644 index 0000000..e3063b1 --- /dev/null +++ b/course-project/starter/report.qmd @@ -0,0 +1,23 @@ +--- +title: "Пингвины с острова Dream" +format: + html: + embed-resources: true +--- + +Данные собраны на трёх островах архипелага Палмера. +Возьмём пингвинов с острова Dream. + +```{r} +penguins <- read.csv("data/penguins.csv") +dream <- subset(penguins, island == "Dream") +nrow(dream) +``` + +Самый длинный плавник: + +```{r} +gigapeng <- max(dream$flipper_len) +gigapeng +``` + diff --git a/course-project/starter/tables.qmd b/course-project/starter/tables.qmd new file mode 100644 index 0000000..723ff22 --- /dev/null +++ b/course-project/starter/tables.qmd @@ -0,0 +1,35 @@ +--- +title: "Статистическая таблица" +format: html +--- + +```{r} +library(tidyverse) +library(flextable) +``` + +```{r} +data <- read_tsv("data/data_tsv.tsv", show_col_types = FALSE) +data$Группа <- factor(data$Группа) + +statistics <- list( + `Количество субъектов` = ~ length(.x), + `Ср. знач.` = ~ mean(.x, na.rm = TRUE), + `Станд. отклон.` = ~ sd(.x, na.rm = TRUE), + `Медиана` = ~ median(.x, na.rm = TRUE) +) + +table <- data |> + select(`Группа`, where(is.numeric)) |> + group_by(`Группа`) |> + summarise(across(where(is.numeric), statistics, .names = "{.col}__{.fn}")) |> + mutate(across(-`Группа`, function(x) round(x, 2))) |> + pivot_longer(!`Группа`) |> + separate(name, into = c("Переменная", "Статистика"), sep = "__") + +table |> + flextable() |> + theme_box() |> + merge_v(c("Группа", "Переменная")) +``` + diff --git a/course-project/updates/penguins.csv b/course-project/updates/penguins.csv new file mode 100644 index 0000000..a8af5f4 --- /dev/null +++ b/course-project/updates/penguins.csv @@ -0,0 +1,345 @@ +"species","island","bill_len","bill_dep","flipper_len","body_mass","sex","year" +"Adelie","Torgersen",39.1,18.7,181,3750,"male",2007 +"Adelie","Torgersen",39.5,17.4,186,3800,"female",2007 +"Adelie","Torgersen",40.3,18,195,3250,"female",2007 +"Adelie","Torgersen",39,,,,,2007 +"Adelie","Torgersen",36.7,19.3,193,3450,"female",2007 +"Adelie","Torgersen",39.3,20.6,190,3650,"male",2007 +"Adelie","Torgersen",38.9,17.8,181,3625,"female",2007 +"Adelie","Torgersen",39.2,19.6,195,4675,"male",2007 +"Adelie","Torgersen",34.1,18.1,193,3475,,2007 +"Adelie","Torgersen",42,20.2,190,4250,,2007 +"Adelie","Torgersen",37.8,17.1,186,3300,,2007 +"Adelie","Torgersen",37.8,17.3,180,3700,,2007 +"Adelie","Torgersen",41.1,17.6,182,3200,"female",2007 +"Adelie","Torgersen",38.6,21.2,191,3800,"male",2007 +"Adelie","Torgersen",34.6,21.1,198,4400,"male",2007 +"Adelie","Torgersen",36.6,17.8,185,3700,"female",2007 +"Adelie","Torgersen",38.7,19,195,3450,"female",2007 +"Adelie","Torgersen",42.5,20.7,197,4500,"male",2007 +"Adelie","Torgersen",34.4,18.4,184,3325,"female",2007 +"Adelie","Torgersen",46,21.5,194,4200,"male",2007 +"Adelie","Biscoe",37.8,18.3,174,3400,"female",2007 +"Adelie","Biscoe",37.7,18.7,180,3600,"male",2007 +"Adelie","Biscoe",35.9,19.2,189,3800,"female",2007 +"Adelie","Biscoe",38.2,18.1,185,3950,"male",2007 +"Adelie","Biscoe",38.8,17.2,180,3800,"male",2007 +"Adelie","Biscoe",35.3,18.9,187,3800,"female",2007 +"Adelie","Biscoe",40.6,18.6,183,3550,"male",2007 +"Adelie","Biscoe",40.5,17.9,187,3200,"female",2007 +"Adelie","Biscoe",37.9,18.6,172,3150,"female",2007 +"Adelie","Biscoe",40.5,18.9,180,3950,"male",2007 +"Adelie","Dream",39.5,16.7,178,3250,"female",2007 +"Adelie","Dream",37.2,18.1,178,3900,"male",2007 +"Adelie","Dream",39.5,17.8,188,3300,"female",2007 +"Adelie","Dream",40.9,18.9,184,3900,"male",2007 +"Adelie","Dream",36.4,17,195,3325,"female",2007 +"Adelie","Dream",39.2,21.1,196,4150,"male",2007 +"Adelie","Dream",38.8,20,190,3950,"male",2007 +"Adelie","Dream",42.2,18.5,180,3550,"female",2007 +"Adelie","Dream",37.6,19.3,181,3300,"female",2007 +"Adelie","Dream",39.8,19.1,184,4650,"male",2007 +"Adelie","Dream",36.5,18,182,3150,"female",2007 +"Adelie","Dream",40.8,18.4,195,3900,"male",2007 +"Adelie","Dream",36,18.5,186,3100,"female",2007 +"Adelie","Dream",44.1,19.7,196,4400,"male",2007 +"Adelie","Dream",37,16.9,185,3000,"female",2007 +"Adelie","Dream",39.6,18.8,190,4600,"male",2007 +"Adelie","Dream",41.1,19,182,3425,"male",2007 +"Adelie","Dream",37.5,18.9,179,2975,,2007 +"Adelie","Dream",36,17.9,190,3450,"female",2007 +"Adelie","Dream",42.3,21.2,191,4150,"male",2007 +"Adelie","Biscoe",39.6,17.7,186,3500,"female",2008 +"Adelie","Biscoe",40.1,18.9,188,4300,"male",2008 +"Adelie","Biscoe",35,17.9,190,3450,"female",2008 +"Adelie","Biscoe",42,19.5,200,4050,"male",2008 +"Adelie","Biscoe",34.5,18.1,187,2900,"female",2008 +"Adelie","Biscoe",41.4,18.6,191,3700,"male",2008 +"Adelie","Biscoe",39,17.5,186,3550,"female",2008 +"Adelie","Biscoe",40.6,18.8,193,3800,"male",2008 +"Adelie","Biscoe",36.5,16.6,181,2850,"female",2008 +"Adelie","Biscoe",37.6,19.1,194,3750,"male",2008 +"Adelie","Biscoe",35.7,16.9,185,3150,"female",2008 +"Adelie","Biscoe",41.3,21.1,195,4400,"male",2008 +"Adelie","Biscoe",37.6,17,185,3600,"female",2008 +"Adelie","Biscoe",41.1,18.2,192,4050,"male",2008 +"Adelie","Biscoe",36.4,17.1,184,2850,"female",2008 +"Adelie","Biscoe",41.6,18,192,3950,"male",2008 +"Adelie","Biscoe",35.5,16.2,195,3350,"female",2008 +"Adelie","Biscoe",41.1,19.1,188,4100,"male",2008 +"Adelie","Torgersen",35.9,16.6,190,3050,"female",2008 +"Adelie","Torgersen",41.8,19.4,198,4450,"male",2008 +"Adelie","Torgersen",33.5,19,190,3600,"female",2008 +"Adelie","Torgersen",39.7,18.4,190,3900,"male",2008 +"Adelie","Torgersen",39.6,17.2,196,3550,"female",2008 +"Adelie","Torgersen",45.8,18.9,197,4150,"male",2008 +"Adelie","Torgersen",35.5,17.5,190,3700,"female",2008 +"Adelie","Torgersen",42.8,18.5,195,4250,"male",2008 +"Adelie","Torgersen",40.9,16.8,191,3700,"female",2008 +"Adelie","Torgersen",37.2,19.4,184,3900,"male",2008 +"Adelie","Torgersen",36.2,16.1,187,3550,"female",2008 +"Adelie","Torgersen",42.1,19.1,195,4000,"male",2008 +"Adelie","Torgersen",34.6,17.2,189,3200,"female",2008 +"Adelie","Torgersen",42.9,17.6,196,4700,"male",2008 +"Adelie","Torgersen",36.7,18.8,187,3800,"female",2008 +"Adelie","Torgersen",35.1,19.4,193,4200,"male",2008 +"Adelie","Dream",37.3,17.8,191,3350,"female",2008 +"Adelie","Dream",41.3,20.3,194,3550,"male",2008 +"Adelie","Dream",36.3,19.5,190,3800,"male",2008 +"Adelie","Dream",36.9,18.6,189,3500,"female",2008 +"Adelie","Dream",38.3,19.2,189,3950,"male",2008 +"Adelie","Dream",38.9,18.8,190,3600,"female",2008 +"Adelie","Dream",35.7,18,202,3550,"female",2008 +"Adelie","Dream",41.1,18.1,205,4300,"male",2008 +"Adelie","Dream",34,17.1,185,3400,"female",2008 +"Adelie","Dream",39.6,18.1,186,4450,"male",2008 +"Adelie","Dream",36.2,17.3,187,3300,"female",2008 +"Adelie","Dream",40.8,18.9,208,4300,"male",2008 +"Adelie","Dream",38.1,18.6,190,3700,"female",2008 +"Adelie","Dream",40.3,18.5,196,4350,"male",2008 +"Adelie","Dream",33.1,16.1,178,2900,"female",2008 +"Adelie","Dream",43.2,18.5,192,4100,"male",2008 +"Adelie","Biscoe",35,17.9,192,3725,"female",2009 +"Adelie","Biscoe",41,20,203,4725,"male",2009 +"Adelie","Biscoe",37.7,16,183,3075,"female",2009 +"Adelie","Biscoe",37.8,20,190,4250,"male",2009 +"Adelie","Biscoe",37.9,18.6,193,2925,"female",2009 +"Adelie","Biscoe",39.7,18.9,184,3550,"male",2009 +"Adelie","Biscoe",38.6,17.2,199,3750,"female",2009 +"Adelie","Biscoe",38.2,20,190,3900,"male",2009 +"Adelie","Biscoe",38.1,17,181,3175,"female",2009 +"Adelie","Biscoe",43.2,19,197,4775,"male",2009 +"Adelie","Biscoe",38.1,16.5,198,3825,"female",2009 +"Adelie","Biscoe",45.6,20.3,191,4600,"male",2009 +"Adelie","Biscoe",39.7,17.7,193,3200,"female",2009 +"Adelie","Biscoe",42.2,19.5,197,4275,"male",2009 +"Adelie","Biscoe",39.6,20.7,191,3900,"female",2009 +"Adelie","Biscoe",42.7,18.3,196,4075,"male",2009 +"Adelie","Torgersen",38.6,17,188,2900,"female",2009 +"Adelie","Torgersen",37.3,20.5,199,3775,"male",2009 +"Adelie","Torgersen",35.7,17,189,3350,"female",2009 +"Adelie","Torgersen",41.1,18.6,189,3325,"male",2009 +"Adelie","Torgersen",36.2,17.2,187,3150,"female",2009 +"Adelie","Torgersen",37.7,19.8,198,3500,"male",2009 +"Adelie","Torgersen",40.2,17,176,3450,"female",2009 +"Adelie","Torgersen",41.4,18.5,202,3875,"male",2009 +"Adelie","Torgersen",35.2,15.9,186,3050,"female",2009 +"Adelie","Torgersen",40.6,19,199,4000,"male",2009 +"Adelie","Torgersen",38.8,17.6,191,3275,"female",2009 +"Adelie","Torgersen",41.5,18.3,195,4300,"male",2009 +"Adelie","Torgersen",39,17.1,191,3050,"female",2009 +"Adelie","Torgersen",44.1,18,210,4000,"male",2009 +"Adelie","Torgersen",38.5,17.9,190,3325,"female",2009 +"Adelie","Torgersen",43.1,19.2,197,3500,"male",2009 +"Adelie","Dream",36.8,18.5,193,3500,"female",2009 +"Adelie","Dream",37.5,18.5,199,4475,"male",2009 +"Adelie","Dream",38.1,17.6,187,3425,"female",2009 +"Adelie","Dream",41.1,17.5,190,3900,"male",2009 +"Adelie","Dream",35.6,17.5,191,3175,"female",2009 +"Adelie","Dream",40.2,20.1,200,3975,"male",2009 +"Adelie","Dream",37,16.5,185,3400,"female",2009 +"Adelie","Dream",39.7,17.9,193,4250,"male",2009 +"Adelie","Dream",40.2,17.1,193,3400,"female",2009 +"Adelie","Dream",40.6,17.2,187,3475,"male",2009 +"Adelie","Dream",32.1,15.5,188,3050,"female",2009 +"Adelie","Dream",40.7,17,190,3725,"male",2009 +"Adelie","Dream",37.3,16.8,192,3000,"female",2009 +"Adelie","Dream",39,18.7,185,3650,"male",2009 +"Adelie","Dream",39.2,18.6,190,4250,"male",2009 +"Adelie","Dream",36.6,18.4,184,3475,"female",2009 +"Adelie","Dream",36,17.8,195,3450,"female",2009 +"Adelie","Dream",37.8,18.1,193,3750,"male",2009 +"Adelie","Dream",36,17.1,187,3700,"female",2009 +"Adelie","Dream",41.5,18.5,201,4000,"male",2009 +"Gentoo","Biscoe",46.1,13.2,211,4500,"female",2007 +"Gentoo","Biscoe",50,16.3,230,5700,"male",2007 +"Gentoo","Biscoe",48.7,14.1,210,4450,"female",2007 +"Gentoo","Biscoe",50,15.2,218,5700,"male",2007 +"Gentoo","Biscoe",47.6,14.5,215,5400,"male",2007 +"Gentoo","Biscoe",46.5,13.5,210,4550,"female",2007 +"Gentoo","Biscoe",45.4,14.6,211,4800,"female",2007 +"Gentoo","Biscoe",46.7,15.3,219,5200,"male",2007 +"Gentoo","Biscoe",43.3,13.4,209,4400,"female",2007 +"Gentoo","Biscoe",46.8,15.4,215,5150,"male",2007 +"Gentoo","Biscoe",40.9,13.7,214,4650,"female",2007 +"Gentoo","Biscoe",49,16.1,216,5550,"male",2007 +"Gentoo","Biscoe",45.5,13.7,214,4650,"female",2007 +"Gentoo","Biscoe",48.4,14.6,213,5850,"male",2007 +"Gentoo","Biscoe",45.8,14.6,210,4200,"female",2007 +"Gentoo","Biscoe",49.3,15.7,217,5850,"male",2007 +"Gentoo","Biscoe",42,13.5,210,4150,"female",2007 +"Gentoo","Biscoe",49.2,15.2,221,6300,"male",2007 +"Gentoo","Biscoe",46.2,14.5,209,4800,"female",2007 +"Gentoo","Biscoe",48.7,15.1,222,5350,"male",2007 +"Gentoo","Biscoe",50.2,14.3,218,5700,"male",2007 +"Gentoo","Biscoe",45.1,14.5,215,5000,"female",2007 +"Gentoo","Biscoe",46.5,14.5,213,4400,"female",2007 +"Gentoo","Biscoe",46.3,15.8,215,5050,"male",2007 +"Gentoo","Biscoe",42.9,13.1,215,5000,"female",2007 +"Gentoo","Biscoe",46.1,15.1,215,5100,"male",2007 +"Gentoo","Biscoe",44.5,14.3,216,4100,,2007 +"Gentoo","Biscoe",47.8,15,215,5650,"male",2007 +"Gentoo","Biscoe",48.2,14.3,210,4600,"female",2007 +"Gentoo","Biscoe",50,15.3,220,5550,"male",2007 +"Gentoo","Biscoe",47.3,15.3,222,5250,"male",2007 +"Gentoo","Biscoe",42.8,14.2,209,4700,"female",2007 +"Gentoo","Biscoe",45.1,14.5,207,5050,"female",2007 +"Gentoo","Biscoe",59.6,17,230,6050,"male",2007 +"Gentoo","Biscoe",49.1,14.8,220,5150,"female",2008 +"Gentoo","Biscoe",48.4,16.3,220,5400,"male",2008 +"Gentoo","Biscoe",42.6,13.7,213,4950,"female",2008 +"Gentoo","Biscoe",44.4,17.3,219,5250,"male",2008 +"Gentoo","Biscoe",44,13.6,208,4350,"female",2008 +"Gentoo","Biscoe",48.7,15.7,208,5350,"male",2008 +"Gentoo","Biscoe",42.7,13.7,208,3950,"female",2008 +"Gentoo","Biscoe",49.6,16,225,5700,"male",2008 +"Gentoo","Biscoe",45.3,13.7,210,4300,"female",2008 +"Gentoo","Biscoe",49.6,15,216,4750,"male",2008 +"Gentoo","Biscoe",50.5,15.9,222,5550,"male",2008 +"Gentoo","Biscoe",43.6,13.9,217,4900,"female",2008 +"Gentoo","Biscoe",45.5,13.9,210,4200,"female",2008 +"Gentoo","Biscoe",50.5,15.9,225,5400,"male",2008 +"Gentoo","Biscoe",44.9,13.3,213,5100,"female",2008 +"Gentoo","Biscoe",45.2,15.8,215,5300,"male",2008 +"Gentoo","Biscoe",46.6,14.2,210,4850,"female",2008 +"Gentoo","Biscoe",48.5,14.1,220,5300,"male",2008 +"Gentoo","Biscoe",45.1,14.4,210,4400,"female",2008 +"Gentoo","Biscoe",50.1,15,225,5000,"male",2008 +"Gentoo","Biscoe",46.5,14.4,217,4900,"female",2008 +"Gentoo","Biscoe",45,15.4,220,5050,"male",2008 +"Gentoo","Biscoe",43.8,13.9,208,4300,"female",2008 +"Gentoo","Biscoe",45.5,15,220,5000,"male",2008 +"Gentoo","Biscoe",43.2,14.5,208,4450,"female",2008 +"Gentoo","Biscoe",50.4,15.3,224,5550,"male",2008 +"Gentoo","Biscoe",45.3,13.8,208,4200,"female",2008 +"Gentoo","Biscoe",46.2,14.9,221,5300,"male",2008 +"Gentoo","Biscoe",45.7,13.9,214,4400,"female",2008 +"Gentoo","Biscoe",54.3,15.7,231,5650,"male",2008 +"Gentoo","Biscoe",45.8,14.2,219,4700,"female",2008 +"Gentoo","Biscoe",49.8,16.8,230,5700,"male",2008 +"Gentoo","Biscoe",46.2,14.4,214,4650,,2008 +"Gentoo","Biscoe",49.5,16.2,229,5800,"male",2008 +"Gentoo","Biscoe",43.5,14.2,220,4700,"female",2008 +"Gentoo","Biscoe",50.7,15,223,5550,"male",2008 +"Gentoo","Biscoe",47.7,15,216,4750,"female",2008 +"Gentoo","Biscoe",46.4,15.6,221,5000,"male",2008 +"Gentoo","Biscoe",48.2,15.6,221,5100,"male",2008 +"Gentoo","Biscoe",46.5,14.8,217,5200,"female",2008 +"Gentoo","Biscoe",46.4,15,216,4700,"female",2008 +"Gentoo","Biscoe",48.6,16,230,5800,"male",2008 +"Gentoo","Biscoe",47.5,14.2,209,4600,"female",2008 +"Gentoo","Biscoe",51.1,16.3,220,6000,"male",2008 +"Gentoo","Biscoe",45.2,13.8,215,4750,"female",2008 +"Gentoo","Biscoe",45.2,16.4,223,5950,"male",2008 +"Gentoo","Biscoe",49.1,14.5,212,4625,"female",2009 +"Gentoo","Biscoe",52.5,15.6,221,5450,"male",2009 +"Gentoo","Biscoe",47.4,14.6,212,4725,"female",2009 +"Gentoo","Biscoe",50,15.9,224,5350,"male",2009 +"Gentoo","Biscoe",44.9,13.8,212,4750,"female",2009 +"Gentoo","Biscoe",50.8,17.3,228,5600,"male",2009 +"Gentoo","Biscoe",43.4,14.4,218,4600,"female",2009 +"Gentoo","Biscoe",51.3,14.2,218,5300,"male",2009 +"Gentoo","Biscoe",47.5,14,212,4875,"female",2009 +"Gentoo","Biscoe",52.1,17,230,5550,"male",2009 +"Gentoo","Biscoe",47.5,15,218,4950,"female",2009 +"Gentoo","Biscoe",52.2,17.1,228,5400,"male",2009 +"Gentoo","Biscoe",45.5,14.5,212,4750,"female",2009 +"Gentoo","Biscoe",49.5,16.1,224,5650,"male",2009 +"Gentoo","Biscoe",44.5,14.7,214,4850,"female",2009 +"Gentoo","Biscoe",50.8,15.7,226,5200,"male",2009 +"Gentoo","Biscoe",49.4,15.8,216,4925,"male",2009 +"Gentoo","Biscoe",46.9,14.6,222,4875,"female",2009 +"Gentoo","Biscoe",48.4,14.4,203,4625,"female",2009 +"Gentoo","Biscoe",51.1,16.5,225,5250,"male",2009 +"Gentoo","Biscoe",48.5,15,219,4850,"female",2009 +"Gentoo","Biscoe",55.9,17,228,5600,"male",2009 +"Gentoo","Biscoe",47.2,15.5,215,4975,"female",2009 +"Gentoo","Biscoe",49.1,15,228,5500,"male",2009 +"Gentoo","Biscoe",47.3,13.8,216,4725,,2009 +"Gentoo","Biscoe",46.8,16.1,215,5500,"male",2009 +"Gentoo","Biscoe",41.7,14.7,210,4700,"female",2009 +"Gentoo","Biscoe",53.4,15.8,219,5500,"male",2009 +"Gentoo","Biscoe",43.3,14,208,4575,"female",2009 +"Gentoo","Biscoe",48.1,15.1,209,5500,"male",2009 +"Gentoo","Biscoe",50.5,15.2,216,5000,"female",2009 +"Gentoo","Biscoe",49.8,15.9,229,5950,"male",2009 +"Gentoo","Biscoe",43.5,15.2,213,4650,"female",2009 +"Gentoo","Biscoe",51.5,16.3,230,5500,"male",2009 +"Gentoo","Biscoe",46.2,14.1,217,4375,"female",2009 +"Gentoo","Biscoe",55.1,16,230,5850,"male",2009 +"Gentoo","Biscoe",44.5,15.7,217,4875,,2009 +"Gentoo","Biscoe",48.8,16.2,222,6000,"male",2009 +"Gentoo","Biscoe",47.2,13.7,214,4925,"female",2009 +"Gentoo","Biscoe",47.5,,,,,2009 +"Gentoo","Biscoe",46.8,14.3,215,4850,"female",2009 +"Gentoo","Biscoe",50.4,15.7,222,5750,"male",2009 +"Gentoo","Biscoe",45.2,14.8,212,5200,"female",2009 +"Gentoo","Biscoe",49.9,16.1,213,5400,"male",2009 +"Chinstrap","Dream",46.5,17.9,192,3500,"female",2007 +"Chinstrap","Dream",50,19.5,196,3900,"male",2007 +"Chinstrap","Dream",51.3,19.2,193,3650,"male",2007 +"Chinstrap","Dream",45.4,18.7,188,3525,"female",2007 +"Chinstrap","Dream",52.7,19.8,197,3725,"male",2007 +"Chinstrap","Dream",45.2,17.8,198,3950,"female",2007 +"Chinstrap","Dream",46.1,18.2,178,3250,"female",2007 +"Chinstrap","Dream",51.3,18.2,197,3750,"male",2007 +"Chinstrap","Dream",46,18.9,195,4150,"female",2007 +"Chinstrap","Dream",51.3,19.9,198,3700,"male",2007 +"Chinstrap","Dream",46.6,17.8,193,3800,"female",2007 +"Chinstrap","Dream",51.7,20.3,194,3775,"male",2007 +"Chinstrap","Dream",47,17.3,185,3700,"female",2007 +"Chinstrap","Dream",52,18.1,201,4050,"male",2007 +"Chinstrap","Dream",45.9,17.1,190,3575,"female",2007 +"Chinstrap","Dream",50.5,19.6,201,4050,"male",2007 +"Chinstrap","Dream",50.3,20,197,3300,"male",2007 +"Chinstrap","Dream",58,17.8,181,3700,"female",2007 +"Chinstrap","Dream",46.4,18.6,190,3450,"female",2007 +"Chinstrap","Dream",49.2,18.2,195,4400,"male",2007 +"Chinstrap","Dream",42.4,17.3,181,3600,"female",2007 +"Chinstrap","Dream",48.5,17.5,191,3400,"male",2007 +"Chinstrap","Dream",43.2,16.6,187,2900,"female",2007 +"Chinstrap","Dream",50.6,19.4,193,3800,"male",2007 +"Chinstrap","Dream",46.7,17.9,195,3300,"female",2007 +"Chinstrap","Dream",52,19,197,4150,"male",2007 +"Chinstrap","Dream",50.5,18.4,200,3400,"female",2008 +"Chinstrap","Dream",49.5,19,200,3800,"male",2008 +"Chinstrap","Dream",46.4,17.8,191,3700,"female",2008 +"Chinstrap","Dream",52.8,20,205,4550,"male",2008 +"Chinstrap","Dream",40.9,16.6,187,3200,"female",2008 +"Chinstrap","Dream",54.2,20.8,201,4300,"male",2008 +"Chinstrap","Dream",42.5,16.7,187,3350,"female",2008 +"Chinstrap","Dream",51,18.8,203,4100,"male",2008 +"Chinstrap","Dream",49.7,18.6,195,3600,"male",2008 +"Chinstrap","Dream",47.5,16.8,199,3900,"female",2008 +"Chinstrap","Dream",47.6,18.3,195,3850,"female",2008 +"Chinstrap","Dream",52,20.7,210,4800,"male",2008 +"Chinstrap","Dream",46.9,16.6,192,2700,"female",2008 +"Chinstrap","Dream",53.5,19.9,205,4500,"male",2008 +"Chinstrap","Dream",49,19.5,210,3950,"male",2008 +"Chinstrap","Dream",46.2,17.5,187,3650,"female",2008 +"Chinstrap","Dream",50.9,19.1,196,3550,"male",2008 +"Chinstrap","Dream",45.5,17,196,3500,"female",2008 +"Chinstrap","Dream",50.9,17.9,196,3675,"female",2009 +"Chinstrap","Dream",50.8,18.5,201,4450,"male",2009 +"Chinstrap","Dream",50.1,17.9,190,3400,"female",2009 +"Chinstrap","Dream",49,19.6,212,4300,"male",2009 +"Chinstrap","Dream",51.5,18.7,187,3250,"male",2009 +"Chinstrap","Dream",49.8,17.3,198,3675,"female",2009 +"Chinstrap","Dream",48.1,16.4,199,3325,"female",2009 +"Chinstrap","Dream",51.4,19,201,3950,"male",2009 +"Chinstrap","Dream",45.7,17.3,193,3600,"female",2009 +"Chinstrap","Dream",50.7,19.7,203,4050,"male",2009 +"Chinstrap","Dream",42.5,17.3,187,3350,"female",2009 +"Chinstrap","Dream",52.2,18.8,197,3450,"male",2009 +"Chinstrap","Dream",45.2,16.6,191,3250,"female",2009 +"Chinstrap","Dream",49.3,19.9,203,4050,"male",2009 +"Chinstrap","Dream",50.2,18.8,202,3800,"male",2009 +"Chinstrap","Dream",45.6,19.4,194,3525,"female",2009 +"Chinstrap","Dream",51.9,19.5,206,3950,"male",2009 +"Chinstrap","Dream",46.8,16.5,189,3650,"female",2009 +"Chinstrap","Dream",45.7,17,195,3650,"female",2009 +"Chinstrap","Dream",55.8,19.8,207,4000,"male",2009 +"Chinstrap","Dream",43.5,18.1,202,3400,"female",2009 +"Chinstrap","Dream",49.6,18.2,193,3775,"male",2009 +"Chinstrap","Dream",50.8,19,210,4100,"male",2009 +"Chinstrap","Dream",50.2,18.7,198,3775,"female",2009 diff --git a/docs/01-01-about.md b/docs/01-01-about.md index 556109d..71bc9f7 100644 --- a/docs/01-01-about.md +++ b/docs/01-01-about.md @@ -13,7 +13,7 @@ Git автоматически отслеживает изменения во в ![](./img/notFinal.gif){width=400px style="border: 1px solid #ddd"} ::: -Важная особенность Git в том, что участники могут работать и создавать версии независимо друг от друга на своих компьютерах. Каждый может работать над своей задачей, не мешая другим, даже если все редактируют один и тот же файл. Git поможет объединить изменения в одну общую версию. +Важная особенность Git в том, что пользователи могут работать и создавать версии независимо друг от друга на своих компьютерах. Каждый может работать над своей задачей, не мешая другим, даже если все редактируют один и тот же файл. Git поможет объединить изменения в одну общую версию. diff --git a/docs/01-02-install.md b/docs/01-02-install.md index 9c4f972..520d7b4 100644 --- a/docs/01-02-install.md +++ b/docs/01-02-install.md @@ -3,14 +3,14 @@ ## Проверьте наличие Git {#terminal} В комплекте с дистрибутивом Git устанавливается программа для терминала. -Чтобы её запустить, откройте Rstudio и в верхнем меню выберите **Tools → Terminal → New Terminal**. +Чтобы открыть терминал в Positron, вызовите поиск команд комбинацией клавиш Ctrl + Shift + P, найдите и выберите **Terminal: Create New Terminal**. В появившемся окне терминала введите команду `git` и нажмите клавишу Enter. Если вы видите результат как на скриншоте ниже, то Git установлен. Иначе нужно его установить --- см. инструкцию для вашей операционной системы ниже. -После установки перезапустите RStudio и повторите проверку. +После установки перезапустите Positron и повторите проверку. -![](./img/git.png){width="100%"} +![](./img/SCR-20260826-ofub.png){width="100%"} ## Windows diff --git a/docs/01-03-shell.md b/docs/01-03-shell.md index 5bd75b6..20f71a7 100644 --- a/docs/01-03-shell.md +++ b/docs/01-03-shell.md @@ -4,13 +4,14 @@ Команды для терминала вы встретите в документации и в интернете, ими легко поделиться и использовать в скриптах. Кроме терминала есть много других способов и их даже можно использовать одновременно. -Графические интерфейсы --- все они имеют ограничения и реализуют только часть возможностей Git, но достаточны для решения большинства задач. Это может быть интерфейс, встроенный в другие программы (например [RStudio](https://docs.posit.co/ide/user/ide/guide/tools/version-control.html), [Pycharm](https://www.jetbrains.com/help/pycharm/using-git-integration.html), [VS Code](https://code.visualstudio.com/docs/sourcecontrol/overview)) или самостоятельная программа (например [GitHub Desktop](https://github.com/apps/desktop), [GitKraken](https://www.gitkraken.com) [и многие другие](https://git-scm.com/downloads/guis)); +Графические интерфейсы --- все они имеют ограничения и реализуют только часть возможностей Git, но достаточны для решения большинства задач. Это может быть интерфейс, встроенный в другие программы (например [Positron](https://positron.posit.co/git.html), [Pycharm](https://www.jetbrains.com/help/pycharm/using-git-integration.html), [VS Code](https://code.visualstudio.com/docs/sourcecontrol/overview), [RStudio](https://docs.posit.co/ide/user/ide/guide/tools/version-control.html)) или самостоятельная программа (например [GitHub Desktop](https://github.com/apps/desktop), [GitKraken](https://www.gitkraken.com) [и многие другие](https://git-scm.com/downloads/guis)); Веб-интерфейсы --- прямо на сайте GitHub можно редактировать отдельные файлы, а также выполнять некоторые команды. -В этом курсе мы будем работать с Git одновременно в интерфейсе RStudio и в терминале, как это делает большинство пользователей R каждый день, а также через GitHub. -Поэтому запомните, как запустить терминал в RStudio --- -в верхнем меню выберите **Tools → Terminal → New Terminal** ([см. скриншот в предыдущей главе](#terminal)). +В этом курсе мы будем работать с Git одновременно в интерфейсе Positron и в терминале, как это делает большинство пользователей каждый день, а также через GitHub. +К терминалу можно вернуться в любой момент, переключаясь между вкладками **(1) CONSOLE** и **(2) TERMINAL** на нижней панели Positron. + +![](./img/SCR-20260826-ofub-2.png){width="100%"} Перед началом работы необходимо сделать несколько настроек. Укажите свое имя и адрес электронной почты, чтобы Git верно записывал информацию об авторе изменений. diff --git a/docs/02-01-init.md b/docs/02-01-init.md index 436f077..97947b8 100644 --- a/docs/02-01-init.md +++ b/docs/02-01-init.md @@ -7,35 +7,19 @@ Git может отслеживать изменения в любой папк **Репозиторий** --- это скрытая подпапка `.git`, в которой хранятся версии проекта и информация об изменениях. Всё необходимое для работы Git содержится непосредственно в ней. -Самый простой способ создать репозиторий --- вместе с проектом RStudio. -В верхнем меню выберите [File → New Project]{.figtext}. -В появившемся окне выберите [New directory]{.figtext}, а затем [New Project]{.figtext}. -На последнем шаге в поле [Directory name]{.figtext} введите название папки для проекта: [penguins]{.figtext}. -Она будет создана на вашем компьютере по адресу, указанному в поле [Create project as subdirectory of]{.figtext}. -‼️ Не забудьте поставить галочку напротив опции [ Create a git repository]{.figtext}, иначе проект будет создан без Git репозитория. -После нажатия кнопки [Create Project]{.figtext} окно RStudio перезагрузится с открытым проектом. - - - - - - - - - - -
![](./img/02-01-01-new-project.png){width="320px"}![](./img/02-01-02-new-project.png){width="320px"}
![](./img/02-01-03-new-project.png){width="320px"}![](./img/02-01-04-new-project.png){width="320px"}
- -При следующем запуске RStudio откроет последний проект. -Если этого не произойдет, чтобы открыть проект в верхнем меню выберите [File → Open Project]{.figtext} или [File → Recent Projects]{.figtext}. - -Убедитесь в том, что проект загружен, для этого обратите внимание на следующие элементы интерфейса: -В правом верхнем углу указано название проекта [(A)]{.figref}. -На панели файлов (по умолчанию она в нижнем правом углу) открыта папка с файлами проекта [(B)]{.figref}. - -![](./img/02-01-05-window.png){width="680px"} - -Когда в RStudio открыт проект, R и Git ищут файлы в папке проекта --- это так называемая **рабочая папка или рабочая область**. +Мы продолжим проект из курса «Введение в автоматизацию обработки данных на R». Откройте его в Positron по [инструкции из курса](https://stepik.org/lesson/2482459/step/5?unit=2520221): нажмите [Open]{.figtext} на верхней панели, выберите Open Folder… и найдите нужную папку. + +Если проекта нет, создайте его, как показано [в курсе](https://stepik.org/lesson/2482459/step/2?unit=2520221). Затем создайте папку `data`, скачайте файл [`penguins.csv`](https://stepik.org/media/attachments/lesson/2482459/penguins.csv) и поместите его туда. + +Убедитесь, что папка открыта: в панели [(1) Explorer]{.figtext} должны быть видны файлы, в том числе папка `data`. +Откройте пункт [(2) Source Control]{.figtext} на панели слева и нажмите [Initialize Repository]{.figtext}. +Positron создаст репозиторий в папке проекта. На панели в разделе [Changes]{.figtext} появится список файлов. + +Если у вас нет кнопки [Initialize Repository]{.figtext}, [проверьте установку Git](#install). + +![](./img/SCR-20260826-rxxf.png){width=100%} + +Когда в Positron открыт проект, R и Git ищут файлы в ней --- это так называемая **рабочая папка или рабочая область**.
Подробнее про поиск и адреса файлов. На разных компьютерах, например у разных участников, проект может находиться в разных местах. @@ -43,10 +27,10 @@ Git может отслеживать изменения в любой папк а у пользователя `scruz` допустим `C:\Users\scruz\penguins`. -Если в скрипте использовать полный адрес файла, например: +Если в документе использовать полный адрес файла, например: ```r -read_csv("/Users/mjordan/penguins/data/sample.csv") +read.csv("/Users/mjordan/r-course/data/penguins.csv") ``` то он будет работать только у пользователя `mjordan`. @@ -54,19 +38,29 @@ read_csv("/Users/mjordan/penguins/data/sample.csv") Чтобы он работал у всех, нужно указывать адрес файла относительно рабочей папки. ```r -read_csv("data/sample.csv") +read.csv("data/penguins.csv") ```
-Рассмотрим созданные RStudio файлы: +Внутри папки проекта создана папка репозитория `.git`. Открывать или изменять её содержимое не нужно, поэтому она скрыта. Для работы с репозиторием используют панель [Source Control]{.figtext} и команды в терминале. -- `hello-git.Rproj` --- содержит настройки проекта -- `.gitignore` --- содержит список файлов, которые Git не будет отслеживать; о том, зачем это нужно и как настроить [смотри в отдельном разделе](#gitignore) -- `.git` --- репозиторий; это скрытая папка, чтобы ее увидеть, в меню на панели файлов выберите [More → Show Hidden Files]{.figtext} +
Как увидеть скрытую папку. +Positron не показывает некоторые служебные папки на панели Explorer. +Чтобы увидеть их, откройте терминал и выполните команду: -Если файл `.gitignore` отсутствует, значит, вы не отметили галочку [ Create a git repository]{.figtext} при создании проекта или не установили Git. -[Проверьте наличие Git](#install) и создайте проект заново. +```shell +ls -la +``` + +В Windows может потребоваться другая команда: + +```powershell +Get-ChildItem -Force +``` + +Появится список файлов проекта, в том числе папка `.git`. +
-Итак, у нас есть проект RStudio --- папка, в которой мы будем работать, и +Итак, у нас есть проект --- папка, в которой мы будем работать, и внутри нее Git репозиторий --- скрытая папка, в которой будут храниться версии проекта. Приступим к созданию первой версии. diff --git a/docs/02-02-commit.md b/docs/02-02-commit.md index 5cd252d..4533113 100644 --- a/docs/02-02-commit.md +++ b/docs/02-02-commit.md @@ -5,43 +5,26 @@ Git отслеживает изменения в файлах, находящи а при помощи версий --- или, в терминах Git, **коммитов (commit)**. Коммиты нужно создавать вручную, выбирая, какие файлы вы хотите зафиксировать, добавив в версию. -Откройте в RStudio панель с названием [Git]{.figtext} (по умолчанию она в верхнем правом углу). -В отличие от списка файлов, на ней выводятся только те файлы, которые были изменены по сравнению с последней версией (коммитом). -Так как мы еще не создали ни одной версии, то в списке выводятся оба файла, созданных с проектом: `.gitignore` и `penguins.Rproj` - - -![](./img/02-02-01-window.png){width=680px} - -
Нет панели Git? -Значит, вы не отметили галочку [Create a git repository]{.figtext} при создании проекта или не установили Git. -[Проверьте наличие Git](#install) и [создайте проект заново](#git-init). -
- -Чтобы создать коммит (версию), отметьте файлы галочкой в столбце [Staged]{.figtext}. -Галочка напротив файла означает, что он добавлен в **индекс (staging)** --- -промежуточную область для выбора файлов, которые будут зафиксированы. -Неотмеченные файлы останутся в рабочей папке, но в коммит не попадут. -Вы можете добавить их в следующую версию позже или отменить изменения. -Нажмите кнопку [Commit]{.figtext}. - -![](./img/02-02-02-staging.png){width=400px} - -В открывшемся окне можно подробнее посмотреть, что изменилось в файлах. -Просмотрите изменения и введите краткое описание в поле [Commit message]{.figtext}. -В нашем примере был создан проект, это и будет подходящим описанием. +Откройте в Positron панель [Source Control]{.figtext}. +В отличие от панели с файлами [Explorer]{.figtext}, на ней выводятся только те файлы, которые были изменены по сравнению с последней версией (коммитом). +Так как мы еще не создали ни одной версии, то в списке выводятся все файлы проекта. + +Чтобы создать коммит (версию), наведите на заголовок [Changes]{.figtext} и нажмите `+`. +После этого файлы окажутся в разделе [Staged Changes]{.figtext} --- **индексе (staging)**, +промежуточной области для выбора файлов, которые войдут в новую версию (коммит). +Можно добавлять файлы и по одному, нажимая `+` только напротив нужных. +Файлы, не добавленные в индекс, останутся в рабочей папке, но не войдут в коммит. +Вы можете добавить их в следующую версию позже или отменить изменения, нажав `↶`. + +Введите краткое описание в поле [Message]{.figtext}. +В нашем примере мы закончили курс R, это и будет подходящим описанием: `Добавил файлы курса по R`. Нажмите кнопку [Commit]{.figtext} под текстовым полем. -![](./img/02-02-03-commit.png){width=600px} - -В открывшемся окне не должно быть ошибок, но должно быть сообщение как на изображении ниже. - -![](./img/02-02-04-message.png){width=600px} +![](./img/SCR-20260827-dsdg.png){width=100%} -Закройте окно с сообщением и окно создания коммита, вернитесь к RStudio. -Обратите внимание, теперь панель [Git]{.figtext} со списком измененных файлов пуста --- +Обратите внимание, теперь панель [Source Control]{.figtext} со списком измененных файлов пуста --- это значит, что изменений по сравнению с последней версией, которую мы только что создали, нет. -![](./img/02-02-05-git-pane.png){width=400px} Теперь у нас есть версия проекта, к которой можно вернуться в любой момент и начать работу с этого места. diff --git a/docs/02-03-practice.md b/docs/02-03-practice.md index 09043a9..ab5359c 100644 --- a/docs/02-03-practice.md +++ b/docs/02-03-practice.md @@ -24,85 +24,101 @@ ## Импорт данных -Загрузите файл с данными [penguins.csv](https://github.com/yoursdearboy/git-101/releases/download/penguins/penguins.csv) в папку проекта. -Если нужно открыть папку в файловом менеджере операционной системы, в меню на панели [Files]{.figtext} выберите [More → Show Folder in New Window]{.figtext}. -Вернитесь в RStudio и убедитесь, что файл `penguins.csv` появился на панели [Git]{.figtext}. -![](./img/02-03-01-show-folder.png){width=400px} +Создайте документ Quarto для анализа и сохраните его под названием `paper.qmd` в корне проекта. Вспомнить как это делается можно в [курсе](https://stepik.org/lesson/2482460/step/2?unit=2520222). +Замените содержимое документа кодом ниже и сохраните файл. -Создайте скрипт для анализа. В меню на панели [Files]{.figtext} выберите [New File → R Script]{.figtext} и введите название файла `penguins.R` -![](./img/02-03-02-new-file.png){width=400px} +```` markdown +--- +title: "Длина клюва пингвинов" +format: + html: + embed-resources: true +--- -Скопируйте следующий код для импорта данных и сохраните его в созданном файле. -Выделите обе строки и запустите, нажав кнопку [Run]{.figtext} в правом верхнем углу редактора RStudio. -Если импорт данных работает, в консоли появится вектор из чисел. +```{r} +data <- read.csv("data/penguins.csv") -```r -data <- read.csv("penguins.csv") -data$bill_length_mm +mean(data$bill_len) ``` +```` -Убедитесь, что файл скрипта также появился на панели [Git]{.figtext}. -Добавьте оба файла в индекс, отметив галочкой в столбце [Staged]{.figtext}, и создайте коммит. -В окне коммита обязательно проверьте содержимое скрипта `penguins.R`, -так как часто пользователи забывают сохранить файл перед добавлением в индекс. +Выполните чанк. +Функция `mean()` вернёт `NA`, потому что в данных нет двух значений длины клюва. +Пока вы проходили предыдущий курс, мы поймали этих двух пингвинов и измерили их клювы. +Скачайте [обновлённые данные](https://raw.githubusercontent.com/yoursdearboy/git-101/positron/course-project/updates/penguins.csv) и замените ими файл `data/penguins.csv`. Снова выполните чанк и убедитесь, что средняя длина клюва равна `43.91802`. -![](./img/02-03-03-git-pane.png){width=690px} +На панели [Source Control]{.figtext} появятся два изменения: новый документ `paper.qmd` и обновлённый файл `penguins.csv`. +Выберите его и проверьте, чем новая версия отличается от прежней: +строки из старого файла выделяются красным цветом, а из нового зеленым. -После создания коммита список измененных файлов на панели [Git]{.figtext} должен быть пуст. +Добавьте в индекс и документ `paper.qmd`, и обновлённый файл `penguins.csv`: без данных результат анализа нельзя будет воспроизвести. +Выберите файл `paper.qmd` и проверьте содержимое: если он пустой, вы забыли сохранить файл, а Git работает только с сохраненными изменениями. +Создайте коммит с описанием «Импортировал данные пингвинов». + +![](./img/SCR-20260827-rohb.png){width=100%} + +После создания коммита список изменённых файлов на панели [Source Control]{.figtext} снова должен быть пуст. ## Визуализация Анализ новых данных полезно начинать с исследования распределения. -Для этого присвоим данные с длиной клюва переменной `x` и построим несколько вариантов гистограммы с разной шириной столбца. -Сохраните приведённый ниже код в тот же файл, запустите и посмотрите графики. +Для этого присвоим данные с длиной клюва переменной и построим несколько вариантов гистограммы с разной шириной столбца. +Замените код чанка на приведённый ниже, запустите и посмотрите графики. -```r -data <- read.csv("penguins.csv") -x <- data$bill_length_mm -hist(x, breaks = seq(40, 60, 4)) -hist(x, breaks = seq(40, 60, 2)) -hist(x, breaks = seq(40, 60, 1)) -``` +``` r +data <- read.csv("data/penguins.csv") -После сохранения файл `penguins.R` снова появился в списке изменений на панели [Git]{.figtext}. -Добавьте его в индекс и проверьте изменения в окне коммита. +x <- data$bill_len + +hist(x, breaks = seq(30, 60, 3)) +hist(x, breaks = seq(30, 60, 2)) +hist(x, breaks = seq(30, 60, 1)) +``` -Вы уже могли заметить, что новые строки выделяются зеленым цветом. -Красным цветом выделяются удаленные строки, а неизмененные остаются белыми. +Сохраните файл `paper.qmd` и он опять появится в списке изменений на панели [Source Control]{.figtext}. +Выберите его и проверье изменения: красным - старые строки, зеленым — новые. Такой формат записи изменений называется **«дифф» (diff)**. -Обратите внимание, что по умолчанию Git анализирует строки, а не отдельные слова или символы. -Поэтому получился следующий дифф: старая вторая строка была удалена, новая вторая строка добавлена (см. номера строк слева), хотя мы всего лишь добавили присвоение `x <- ` в начало строки. -![](./img/02-03-04-git-pane.png){width=690px} +Обратите внимание, что по умолчанию Git сравнивает строки, а не отдельные слова или символы. +Несмотря на то, что мы заменили `mean()` на присвоение `x <- ` в 11-й строке, Git показывает прежнюю строку как удалённую, а новую — как добавленную. Номера слева указывают положение этих строк в старой и новой версиях файла. -Убедитесь, что сделанные изменения соответствуют диффу на скриншоте выше, и создайте новый коммит с описанием «Добавили гистограммы для длины клюва». +![](./img/SCR-20260828-cufv.png){width=100%} + +Добавьте `paper.qmd` в индекс, введите описание «Добавил гистограммы для длины клюва» и нажмите [Commit]{.figtext}. +После создания коммита список изменённых файлов снова должен быть пуст. ## Экспорт Гистограмма с шириной столбца 2 выглядит наиболее информативно. -Такой график можно и опубликовать. -Чтобы экспортировать изображение, сохраните следующий код в файл скрипта и запустите его. +Соберём HTML-отчёт, чтобы поделиться с коллегами. + +Оставьте в коде чанка только один вариант гистограммы и сохраните файл. + -```r -data <- read.csv("penguins.csv") -x <- data$bill_length_mm +``` r +data <- read.csv("data/penguins.csv") -png("penguins-hist.png") -hist(x, breaks = seq(40, 60, 2)) -dev.off() +x <- data$bill_len + +hist(x, breaks = seq(30, 60, 2)) ``` -После этого в списке изменений на панели [Git]{.figtext}, кроме файла `penguins.R`, появился файл с изображением `penguins-hist.png`. +Нажмите [Preview]{.figtext} вверху окна редактора. +В корне проекта появится файл `paper.html`. Его мы тоже добавим в коммит. -Во-первых, так другие участники, загрузив проект, сразу увидят результат без необходимости запускать скрипт. +Во-первых, так другие участники, загрузив проект, сразу увидят результат без необходимости выполнять код. Во-вторых, если вы измените ширину столбца или другие настройки графика, будет удобно сравнить старую и новую версии. -Добавьте оба файла в индекс, проверьте изменения, изучив дифф, и создайте коммит с описанием «Сохранили гистограмму длины клюва». +![](./img/SCR-20260828-cvcb.png){width=100%} + +Добавьте оба файла в индекс и создайте коммит с описанием «Собрал отчёт о длине клюва». +Проверьте, что на панели [Source Control]{.figtext} не осталось «незакомиченных» изменений. -На этом остановимся и посмотрим историю версий в журнале Git. +На этом остановимся и далее посмотрим историю версий в журнале Git. +А пока несколько советов. ::: {.callout .callout-info} Делайте коммиты часто и не придавайте слишком большое значение планированию. diff --git a/docs/02-04-log-n-diff.md b/docs/02-04-log-n-diff.md index a531118..e775c34 100644 --- a/docs/02-04-log-n-diff.md +++ b/docs/02-04-log-n-diff.md @@ -5,23 +5,20 @@ Журнал позволяет изучить изменения от других участников или вспомнить свои собственные, и зачем они сделаны. Поэтому так важно писать ясные и содержательные описания коммитов. Используя журнал, можно найти, когда сделаны изменения, приведшие к ошибке, и вернуть проект к предыдущему состоянию. -В конце концов, его можно использовать для отчетности и бизнесс-аналитики по проекту. +В конце концов, его можно использовать для отчетности и бизнес-аналитики по проекту. -Чтобы открыть журнал, нажмите кнопку [History]{.figtext} на панели [Git]{.figtext}. +Чтобы открыть журнал, на панели [Source Control]{.figtext} разверните раздел [Graph]{.figtext} внизу. В открывшемся окне выводится список коммитов в обратном порядке --- последние коммиты находятся вверху. -В списке выводится краткая информация о коммите, а под списком подробная информация по выделенному коммиту. -![](./img/02-04-02-history.png){width=690px} +При наведении на коммит появляется краткая информация: имя автора, которое [мы указали в настройках](#setup), дата и описание, и самое важное — хэш коммита, его уникальный идентификатор. В примере это `967f8ad`, у вас он будет другим. -- SHA --- так называемый хэш коммита, который является его уникальным идентификатором в репозитории -- Author --- автор коммита \, [которые были указаны в настройках](#setup) -- Date --- дата и время создания коммита -- Subject --- описание коммита -- Parent --- хэш (идентификатор) предыдущего коммита +Кликните на коммит, чтобы посмотреть список изменений. Выберите файл, чтобы открыть дифф --- изменения, сделанные в этом коммите по сравнению с предыдущей версией. -Еще ниже показан дифф --- изменения, сделанные в этом коммите по сравнению с предыдущим. -Для больших файлов выводятся только те строки, которые поменялись, а также несколько строк выше и ниже, чтобы был понятен контекст. -Если нажать кнопку [View file]{.figtext} справа от названия файла, можно увидеть его полное содержимое, каким оно было зафиксировано создания коммита. +![](./img/SCR-20260828-dmxx.png){width=100%} + +Если нужна история только одного файла, выберите его на панели [Explorer]{.figtext} и откройте раздел [Timeline]{.figtext} внизу той же панели. +Выберите коммит, чтобы посмотреть изменения. +В разделе [Timeline]{.figtext} также есть автоматические контрольные точки, которые создаются при сохранении файла. Они не входят в Git-репозиторий и исчезнут через некоторое время. Даже если вы работаете в одиночку, полезно иметь под рукой историю изменений. Но по настоящему эта функция полезна, diff --git a/docs/03-01-branches.md b/docs/03-01-branches.md index 83ea721..66f0dd0 100644 --- a/docs/03-01-branches.md +++ b/docs/03-01-branches.md @@ -16,60 +16,51 @@ Git позволяет эффективно объединять эти изме Для этого используются так называемые ветки (branch). Почему ветки? Потому что начиная с выбранного коммита история изменений разветвляется. + +::: {style="float: left; clear: both; width: 200px; margin-right: 20px;"} +![](./img/SCR-20260828-dmxz.png){width=100%} +::: + По умолчанию, мы работаем в ветке `main` (ранее ветка по умолчанию называлась `master`, будьте готовы встретить и такое название). Ее можно сравнить со стволом дерева --- вот он слева на изображении. -В нашем проекте с пингвинами в ветке `main` 4 коммита, последний из которых содержит гистограмму для публикации. - -![](./img/03-01-00-history.png){width=600px} +В нашем проекте с пингвинами в ветке `main` 4 коммита и от любого из них можно начать новую ветку. Представим ситуацию --- из журнала приходит ответ Рецензента 2, в котором он просит заменить гистограмму на ящик с усами. С одной стороны, можно податься в журнал, где знают, что такое гистограмма, с другой, можно хотя бы попробовать удовлетворить пожелания рецензента и, -если нам не понравится новая диаграмма, просто удалить изменения. +если нам не понравится новая диаграмма, просто удалить ветку с изменениями. # Создание ветки {#git-branch} Чтобы спокойно поэкспериментировать создадим новую ветку. Так будет проще удалить изменения и они не будут мешать, если мы захотим поправить что-то действительно важное в основной ветке `main`. -В RStudio нажмите кнопку [New Branch]{.figtext} [(A)]{.figref} - -![](./img/03-01-01-new-branch.png){width=400px} +В Positron нажмите название текущей ветки `main` в строке состояния внизу окна и выберите [Create new branch…]{.figtext}. +В появившемся поле введите название, например `boxplot`, и нажмите Enter. +Positron переключится на новую ветку `boxplot`. +Обратите внимание, что название ветки в строке состояния поменялось с `main` на `boxplot`. -В появившемся окне введите название, например `boxplot` и нажмите кнопку [Create]{.figtext}. -Откроется окно с сообщением, что мы переключились на ветку `boxplot`, -можете закрыть его кнопкой [Close]{.figtext}. +![](./img/SCR-20260829-ckqm.png){width=100%} -![](./img/03-01-02-new-branch.png){width=200px} - -![](./img/03-01-03-new-branch.png){width=400px} +Вернемся к пингвинам. +Замените вызов `hist()` в чанке на вызов `boxplot()`: -Обратите внимание, что название ветки на панели [Git]{.figtext}, рядом с кнопкой создания ветки [(A)]{.figref}, поменялось с `main` на `boxplot`. -Вернемся к пингвинам. -Замените содержимое скрипта `penguins.R` на следующее: +``` r +data <- read.csv("data/penguins.csv") -```r -data <- read.csv("penguins.csv") -x <- data$bill_length_mm +x <- data$bill_len -png("penguins-boxplot.png") boxplot(x) -dev.off() ``` -Сохраните файл и выполните скрипт. -Обратите внмание, что мы поменяли название файла. -Старый файл `penguins-hist.png` в этой версии нам не нужен и его необходимо удалить. -Не переживайте, благодаря Git, в основной ветке `main` он останется. -На панели [Files]{.figtext} отметьте галочкой файл `penguins-hist.png` [(A)]{.figref} и нажмите кнопку [Delete]{.figtext} [(B)]{.figref}. - -![](./img/03-01-04-delete-files.png){width=400px} +Сохраните файл и нажмите [Preview]{.figtext}, чтобы обновить отчёт `paper.html`. +Не переживайте, благодаря Git в основной ветке `main` останется прежний вариант с гистограммой. -Отметьте все изменения для фиксации и создайте коммит. -Обратите внимание, что удаление файла это тоже изменение, которое надо отметить. +Отметьте все изменения для фиксации и создайте коммит с описанием «Заменил гистограмму на ящик с усами». +Обратите внимание, что в коммит должны попасть и исходный документ `paper.qmd`, и обновлённый отчёт `paper.html`. -![](./img/03-01-05-commit.png){width=400px} +![](./img/SCR-20260829-cltf.png){width=100%} Теперь отложим эксперименты и вернемся к прежней версии. diff --git a/docs/03-02-checkout.md b/docs/03-02-checkout.md index 9bfc862..3167504 100644 --- a/docs/03-02-checkout.md +++ b/docs/03-02-checkout.md @@ -1,35 +1,41 @@ # Переключение веток {#git-checkout} -Для переключения ветки нажмите на название текущей ветки [(A)]{.figref} на панели [Git]{.figtext}. +Для переключения ветки нажмите на название текущей ветки в строке состояния Positron. В выпадающем списке выберите ветку на которую хотите переключиться (`main`). -![](./img/03-02-01-branch.png){width=400px} +![](./img/SCR-20260829-cqic.png){width=100%} -Убедитесь, что код скрипта вернулся к прежнему состоянию и строит гистограмму, -а в списке файлов находится файл с гистограммой `penguins-hist.png` и нету файла `penguins-boxplot.png`. - -![](./img/03-02-02-files.png){width=400px} +Убедитесь, что код документа `paper.qmd` вернулся к прежнему состоянию и вызывает функцию `hist()`, +а отчёт в окне просмотра строит гистограмму вместо ящика с усами. Это было просто. Но есть один случай, когда Git откажется переключать ветку --- если это приведет к потере данных. -Например, замените содержимое скрипта `penguins.R` на следующее (добавилась подпись оси X): +Например, замените код чанка на следующий (добавилась подпись оси X): + -```r -data <- read.csv("penguins.csv") -x <- data$bill_length_mm +``` r +data <- read.csv("data/penguins.csv") -png("penguins-hist.png") -hist(x, breaks = seq(40, 60, 2), xlab = "Bill length, mm") -dev.off() +x <- data$bill_len + +hist(x, breaks = seq(30, 60, 2), xlab = "Bill length, mm") ``` +::: {style="float: left; clear: both; width: 200px; margin-right: 20px;"} +![](./img/SCR-20260829-dlcs.png){width=100%} +::: + Сохраните файл и попробуйте переключиться на ветку `boxplot`. -Вы получите сообщение как на скриншоте ниже. -Если бы Git переключил ветку, ему бы пришлось перезаписать файл `penguins.R`, в который мы внесли изменения, но не зафиксировали. -Поэтому, чтобы не потерять изменения при переключении, сначала необходимо их зафиксировать создав коммит. +Вы увидите сообщение, как на скриншоте слева. +Если бы Git переключил ветку, ему бы пришлось перезаписать файл `paper.qmd`, в который мы внесли изменения, но не зафиксировали. +Positron предлагает временно спрятать изменения (**Stash**), чтобы можно было переключиться. +Но есть решение лучше — зафиксировать их создав коммит. +Нажмите **Cancel**, чтобы отменить переключение. +Добавьте изменения в индекс и создайте коммит с описанием «Добавил подпись оси». -![](./img/03-02-03-error.png){width=690px} +![](./img/SCR-20260829-damx.png){width=100%} -Создайте коммит и попробуйте переключиться на ветку `boxplot` и обратно на ветку `main`. +Попробуйте снова переключиться на ветку `boxplot`. +На этот раз переключение должно пройти без ошибок (убедитесь, что код в редакторе изменился). diff --git a/docs/03-03-merge.md b/docs/03-03-merge.md index a73aef7..903805e 100644 --- a/docs/03-03-merge.md +++ b/docs/03-03-merge.md @@ -1,23 +1,21 @@ # Слияние веток {#git-merge} -[Откройте окно истории](#git-log) и выберите в фильтре сверху показывать все ветки [(all branches)]{.figtext} и все коммиты [(all commits)]{.figtext}. -На диграмме наглядно видно почему это называется веткой. +На панели [Source Control]{.figtext} разверните раздел [Graph]{.figtext} внизу, как показано в главе +[просмотр истории](#git-log). +Справа от заголовка [Graph]{.figtext} нажмите [Auto]{.figtext} с иконкой ветки +и в выпадающем меню выберите [All]{.figtext}. +Диаграмма покажет обе ветки, и теперь должно быть ясно, почему они так называются. -![](./img/03-03-01-log.png){width=690px} +![](./img/SCR-20260829-dtuv.png){width=100%} -Если мы или другой участник проекта, решим принять эти изменения в основную ветку `main`, -нам нужно выполнить операцию «слияния» (merge). -В RStudio нет встроенной возможности слияния веток, это необходимо делать в терминале. -К счастью, команда совсем не сложная. +Если мы или другой участник проекта решим принять эти изменения в основную ветку `main`, +нам нужно выполнить операцию **«слияния» (merge)**. Для начала переключитесь на ветку, в которую будут вливаться изменения --- в нашем случае это `main` ([см. переключение веток](#git-checkout)). -Откройте терминал ^[В меню RStudio выберите Tools → Terminal → New Terminal] и введите команду для слияния с веткой `boxplot`. +На панели [Source Control]{.figtext} нажмите кнопку с троеточием справа от заголовка [Changes]{.figtext}. Выберите [Branch → Merge…]{.figtext}, а затем --- ветку `boxplot`. -```sh -git merge boxplot - -``` +![](./img/SCR-20260829-dzjy.png){width=100%} Git попытается автоматически объединить изменения из обеих веток и создать новый коммит. В большинстве случаев этого достаточно, @@ -27,68 +25,60 @@ Git попытается автоматически объединить изм Git предпочтет выдать ошибку и попросит вас разрешить конфликт. В списке изменений мы видим, -что Git автоматически выбрал изменения связанные с новым и старым файлом для графика -`penguins-hist.png` и `penguins-boxplot.png`, -но лишь частично для скрипта `penguins.R`. +что Git автоматически добавил в индекс отчёт `paper.html` из ветки `boxplot`, +но не документ `paper.qmd`, который отмечен восклицательным знаком. + +Причина в том, что после изменения кода графика в ветке `boxplot` +мы изменили ту же строку в ветке `main`. +Откройте файл `paper.qmd`. +Git сохранил в нём обе версии кода и разделил их специальными маркерами: -![](./img/03-03-02-git-pane.png){width=400px} +- после строки `<<<<<<< HEAD` идёт версия из текущей ветки `main`, выделенная зелёным; +- строка `=======` отделяет две версии друг от друга; +- строка `>>>>>>> boxplot` завершает версию из ветки `boxplot`, выделенную синим. -Причина в том, что мы вносили изменения в код графика в ветке `main` после того как изменили его в ветке `boxplot`. -Откройте файл `penguins.R`. -Git любезно оставил для нас обе версии кода разделив специальными символами. -После строки `<<< HEAD` идет версия из текущей ветки, -строка `===` отделяет две версии друг от друга, -а строка `>>> boxplot` завершает версию из ветки `boxplot`. +![](./img/SCR-20260829-dzmv.png){width=100%} -![](./img/03-03-03-merge-conflict.png){width=690px} +Нам нужно объединить изменения в одну версию и удалить маркеры. +Важно понимать, что это не часть интерфейса Positron, а обычный текст, который Git вставил прямо в файл. +Поэтому вместо одной строки у нас теперь пять (строки 13-17) и это не валидный синтаксис R: +попробуйте нажать **Preview** или выполнить чанк и убедитесь в этом. -Наша задача переписать выделенный участок (строки 4-12) в одну версию и убрать спецсимволы. -Важно понимать, что Git просто вставил в скрипт кусок текста, -но это все еще обычный R скрипт и мы должны привести его в рабочее состояние. +Приведем документ в рабочее состояние: +за основу возьмём версию из ветки `boxplot`, но добавим в неё подпись оси из ветки `main`. +Удалите строки 13-15 со старой версией и разделяющими маркерами. +Добавьте подпись оси в вызов `boxplot()`. +У ящика с усами длина клюва показана по оси Y, поэтому для подписи используем аргумент `ylab`. +Также удалите строку 17 с маркером `>>>>>>>`. +В итоге должен получиться такой код. -Нам нужна версия из ветки `boxplot`, но мы хотим добавить в нее подпись оси, как это было сделано в ветке `main`. -Для этого оставим нижнюю версию (строки 9-11) и удалим лишние строки (4-8 и 12) -и добавим подпись, только для ящика с усами это должна быть подпись оси Y. -В итоге должен получиться следующий код. -```r -data <- read.csv("penguins.csv") -x <- data$bill_length_mm +``` r +data <- read.csv("data/penguins.csv") + +x <- data$bill_len -png("penguins-boxplot.png") boxplot(x, ylab = "Bill length, mm") -dev.off() ``` -Сохраните файл и выполните скрипт. -Создайте коммит и -не забудьте отметить галочкой внесенные изменения, -в том числе обновившийся файл `penguins-boxplot.png`, который теперь содержит подпись оси. -Обычно сообщение коммита о слиянии веток содержит следующий текст «Merge branch название-ветки», но можете придумать свое. +Сохраните файл и нажмите [Preview]{.figtext}, чтобы обновить отчёт. +Добавьте в индекс изменённые файлы `paper.qmd` и `paper.html`. +Отчёт обновился, потому что по сравнению с версией из ветки `boxplot` в нём появилась подпись оси. +Создайте коммит. +Описание слияния обычно выглядит так: «Merge branch название-ветки», +но можете написать своё. -![](./img/03-03-04-git-pane.png){width=400px} +![](./img/SCR-20260829-nppw.png){width=100%} Итак, мы успешно слили изменения из ветки `boxplot` в основную ветку `main`. Теперь можно продолжить работу в основной ветке. Еще лучше будет создать очередную ветку для новых изменений, выполнить работу в ней и точно так же слить в основную. -![](./img/03-03-05-log.png){width=690px} - -
Как удалить ветку? Слитую ветку можно удалить. -В RStudio для этого нет встроенных средств, поэтому придется использовать терминал. -Выполните команду: +На панели [Source Control]{.figtext} нажмите кнопку с троеточием справа от заголовка [Changes]{.figtext}. +Выберите [Branch → Delete Branch…]{.figtext}, а затем ветку `boxplot`. -```sh -git branch -d boxplot -``` - -Если ветка не была слита, Git откажется ее удалять, ведь могут быть потеряны сделанные в ней изменения. -Если вы действительно уверены, что они вам не нужны и вы хотите удалить не слитую ветку, выполните команду: - -```sh -git branch -D boxplot -``` -
+Если ветка не была слита, Git предупредит, что при удалении можно потерять сделанные в ней изменения. +Удаляйте такую ветку только в том случае, если уверены, что изменения больше не нужны. diff --git a/docs/04-01-github.md b/docs/04-01-github.md index 928b329..20f3502 100644 --- a/docs/04-01-github.md +++ b/docs/04-01-github.md @@ -6,34 +6,10 @@ GitHub --- это веб-сервис для хранения Git репозит Ваши файлы размещаются на удаленном сервере и доступны публично или приватно для загрузки другими пользователями. В некотором смысле это аналог Dropbox или Google Drive для Git. Помимо хранения репозиториев, GitHub предоставляет другие инструменты: отслеживание задач, обсуждение изменений, запуск тестов и сборок и многое другое. -Для работы с GitHub вам понадобится зарегистрировать учетную запись и создать токен --- отдельный пароль для Git на вашем компьютере. - -## Регистрация на GitHub - -Перейдите на сайт github.com и зарегистрируйте учетную запись нажав на кнопку [Sign up]{.figtext} в верхнем правом углу или войдите в существующую учетную запись нажав [Sign in]{.figtext}. +Для работы с GitHub нужна учётная запись. Откройте github.com. +Если учётной записи нет, нажмите [Sign up]{.figtext} в правом верхнем углу и зарегистрируйтесь. Если она уже есть, нажмите [Sign in]{.figtext} и войдите. E-mail при регистрации не обязательно должен совпадать с указанным при настройке Git в [Главе 1](#setup). Дополнительные e-mail адреса можно добавить после регистрации [на странице настроек](https://github.com/settings/emails). Это рекоммендуется сделать, чтобы GitHub мог ассоциировать сделанные на компьютере коммиты с вашей учетной записью онлайн. -## Создание токена - -В целях безопасности, GitHub не позволяет использовать пароль от веб-сайта при работе с Git, -а требует создать так называемый **Personal Access Token** --- отдельный пароль специально для Git на вашем компьютере. -[Во всех случаях, когда Git запрашивает пароль от GitHub, необходимо вводить токен, а не пароль от веб-сайта.]{} - -Для этого перейдите по ссылке github.com/settings/tokens, -авторизуйтесь и нажмите **Generate new token**, в выпадающем списке выберите **classic**. -На новой странице введите название токена, например Work. -Отметьте следующие права `repo`, `workflow`, `user` -и нажмите зеленую кнопку **Generate token** в конце страницы. - -![](img/github-1.png){width=100%} -![](img/github-2.png){width=100%} - -Не забудьте скопировать и сохранить ваш токен - он выглядит как строка вида `ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`. -После того как вы закроете страницу посмотреть созданный токен невозможно. -Храните его в надежном месте как пароль. - -![](img/github-3.png){width=100%} - Теперь мы готовы опубликовать наш репозиторий на GitHub. diff --git a/docs/04-02-remote.md b/docs/04-02-remote.md index 5db3803..0cd29fb 100644 --- a/docs/04-02-remote.md +++ b/docs/04-02-remote.md @@ -1,4 +1,4 @@ -# Удаленный репозиторий {#git-remote} +# Удалённый репозиторий {#git-remote} @@ -7,37 +7,44 @@ ![](./img/04-02-01-new-repository.png){width=400px} -В открывшейся форме достаточно заполнить только название репозитория в поле **Repository name**, например `penguins`. +В открывшейся форме достаточно заполнить только название репозитория в поле **Repository name**, например `r-course`. Остальные поля оставьте по умолчанию, мы только разберем за что они отвечают. -- Description --- краткое описание -- Public / Private --- настройка доступа +- **Description** --- краткое описание +- **Choose visibility** --- настройка доступа - Public --- кто угодно сможет просматривать ваши файлы, но только отдельно добавленные пользователи смогут их изменять - Private --- только отдельно добавленные пользователи смогут просматривать и изменять файлы -- Initialize this repository with --- этот раздел позволяет добавить в создаваемый репозиторий несколько типовых файлов `README` `.gitignore` и `LICENSE`; не отмечайте ни один из них, потому что в нашем репозитории на компьютере уже есть файлы и они будут конфликтовать с этими. +- **Add README**, **.gitignore**, **license** добавляет в создаваемый репозиторий шаблоны этих файлов; не отмечайте ни один, потому что в нашем репозитории на компьютере уже есть файлы и они будут конфликтовать с этими. Внизу страницы нажмите [Create repository]{.figtext}.
Пример заполненной формы -![](./img/04-02-02-new-repository.png){width=600px} +![](./img/SCR-20260829-obrj.png){width=600px}
-*Удалить это? Там и так на форме все написано, только что на англ. Оставить только предупреждение, чтобы не жали Initialize this repository with.* -*Со скрином формы репозитория тоже ту мач?* -Для созданного репозитория GitHub сгенерировал набор команд быстрой настройки, воспользуемся ими. -Сначала необходимо убедиться, что напротив адреса репозитория выбрана опция доступа через [HTTPS]{.figtext} [(A)]{.figref}. -Далее скопируйте все три команды из раздела для существующего репозитория (**... or push an existing repository from the command line**, [B]{.figref}) и выполните в терминале ^[В меню RStudio выберите Tools → Terminal → New Terminal]. -На запрос пароля скопируйте и вставьте сгенерированный в предыдущей главе токен. +Для созданного репозитория GitHub сгенерировал набор команд для быстрой настройки, воспользуемся ими. +Сначала необходимо убедиться, что напротив адреса репозитория выбрана опция доступа через [HTTPS]{.figtext} [(1)]{.figref}. -![](./img/04-02-03-git-push.png){width=100%} +![](./img/SCR-20260830-cmvs.png){width=100%} +Далее скопируйте все три команды из раздела для существующего репозитория (**... or push an existing repository from the command line**, [2]{.figref}) и выполните их в терминале. Если закрыли терминал или он занят Quarto, [создайте новый терминал](#terminal). +Positron предложит войти в GitHub. Выберите [Allow]{.figtext}, +запомните код появившийся в новом окне, затем нажмите [Copy & Continue to Browser]{.figtext}. + +![](./img/SCR-20260830-coos.png){width=100%} + +В открывшемся окне браузера разрешите доступ, введите код и завершите вход. +Вернитесь в Positron. + + + +Мы связали наш локальный репозиторий с удаленным при помощи команды `git remote add` --- это необходимо было сделать один раз. +И выполнили команду `git push` --- отправить локальные коммиты в удаленный репозиторий, это необходимо делать регулярно и для этого Positron есть интерфейс. -Мы связали наш локальный репозиторий с удаленным при помощи команды **remote add** --- это необходимо было сделать один раз. -И выполнили команду **push** --- отправить сделанные фиксации в удаленный репозиторий, это необходимо делать регулярно и для этого в интерфейсе RStudio есть кнопка на панели [Git]{.figtext}. Если команды выполнились успешно, файлы были загружены на GitHub. Обновите страницу репозитория и проверьте содержимое файлов. -![](./img/04-02-04-github.png){width=100%} +![](./img/SCR-20260830-dcfe.png){width=100%} diff --git a/docs/04-03-push-pull.md b/docs/04-03-push-pull.md index 978d26b..5057ea8 100644 --- a/docs/04-03-push-pull.md +++ b/docs/04-03-push-pull.md @@ -2,65 +2,63 @@ -На предыдущем шаге мы загрузили изменения из нашего локального репозитория в удаленный репозиторий на GitHub при помощи команды `push` в терминале. +На предыдущем шаге мы загрузили изменения из локального репозитория в удалённый репозиторий на GitHub при помощи команды `git push` в терминале. +Git не синхронизирует изменения автоматически, это необходимо делать вручную. -Git не синхронизирует изменения автоматически, это необходимо делать вручную, используя команду push ил кнопку [Push]{.figtext} в интерфейсе RStudio на панели [Git]{.figtext}. +Создадим и загрузим ещё один коммит. Добавьте в `paper.qmd` перед чанком с графиком короткое пояснение, например: -Создадим и загрузим еще один коммит. Например, добавим небольшой комментарий к коду, чтобы человеку открывшему его впервые было легче разобраться. - -```r -data <- read.csv("penguins.csv") -x <- data$bill_length_mm - -# Ящик с усами для длины клюва - -png("penguins-boxplot.png") -boxplot(x, ylab = "Bill length, mm") -dev.off() +``` +Ящик с усами для длины клюва. ``` -Сохраните и закомитьте файл `penguins.R`. -После чего нажмите кнопку [Push]{.figtext} в верхнем правом углу. +Сохраните и закомитьте файл `paper.qmd`. +После чего нажмите кнопку [Sync Changes]{.figtext} на панели [Source Control]{.figtext}. -![](./img/04-03-01-git-push.png){width=100%} +![](./img/SCR-20260830-dpri.png){width=100%} Перейдите на страницу репозитория на GitHub и убедитесь, что коммит был загружен. -Это можно понять по тексту сообщения над списком файлов и по тексту и времени изменения напротив файла `penguins.R`. +Это можно понять по тексту сообщения над списком файлов и по тексту и времени изменения напротив файла `paper.qmd`. -![](./img/04-03-02-github.png){width=100%} +![](./img/SCR-20260830-dqwa.png){width=100%} GitHub позволяет вносить изменения в репозиторий из веб-интерфейса. Эта функция используется редко, потому что код необходимо запускать и проверять на компьютере, но она полезна для небольших правок или загрузки файлов. Создадим при помощи нее новый файл. -Файл README --- это файл, который отображается на главной странице репозитория для краткого описания проекта. Обычно он включает описание данных и скриптов, как начать работу с проектом и тому подобное. +Файл README --- это файл, который отображается на главной странице репозитория для краткого описания проекта. Обычно он включает описание данных и кода, как начать работу с проектом и тому подобное. -Нажмите кнопку [Add a README]{.figtext}. В открывшемся файле введите текст в формате Markdown^[это как RMarkdown, только без возможности выполнения кода на R] (используйте или измените текст ниже) +Нажмите кнопку [Add a README]{.figtext}. В открывшемся файле введите текст в формате Markdown^[в документе Quarto используется тот же синтаксис разметки, но README не выполняет код на R] (используйте или измените текст ниже) и нажмите кнопку [Commit changes]{.figtext} в верхнем правом углу. Откроется окно создания коммита, оставьте текст по умолчанию и подтвердите создание коммита нажатием кнопки [Commit changes]{.figtext} -![](./img/04-03-03-add-readme.png){width=100%} +![](./img/SCR-20260830-dtys.png){width=100%} ```md -# Пингвины «Палмер» 🐧 +# Учебный проект -Этот репозиторий был создан в рамках курса от [Института биоинформатики](bioinf.me/education/stat), -чтобы познакомиться с основами Git — фиксацией изменений, ветвлением и работой с GitHub. +Этот репозиторий был создан в рамках курса [«Основы Git»](https://yoursdearboy.github.io/git-101/), +чтобы познакомиться с фиксацией изменений, ветвлением и работой с GitHub. -В качестве примера использованы данные о длине клюва пингвинов, +В качестве примера использованы данные о длине клюва 🐧 пингвинов, собранные доктором Кристен Горман на станции «Палмер» в Антарктиде. -Содержимое репозитория: +Файлы проекта: -- penguins-boxplot.png — диаграмма ящик с усами, показывающая распределение длины клюва -- penguins.R — скрипт для построения диаграммы -- penguins.csv — данные +- `paper.html` — готовый отчёт +- `paper.qmd` — документ Quarto с кодом +- `data/penguins.csv` — данные ``` -Чтобы загрузить изменения из удаленного репозитория на компьютер используется команда **pull**. +Загрузить изменения из удалённого репозитория можно двумя способами: выполнить команду `git pull` в терминале или нажать кнопку [Pull]{.figtext} справа от заголовка [Graph]{.figtext} на панели [Source Control]{.figtext} в Positron. + +::: {style="float: left; clear: both; width: 200px; margin-right: 20px;"} +![](./img/SCR-20260830-dzhz.png){width=100%} +::: + +Загрузите изменения любым из этих способов. +Если загрузка прошла успешно, в журнале появится коммит созданный через GitHub, а в списке файлов `README.md`. -Вернитесь в RStudio и на панели [Git]{.figtext} нажмите кнопку [Pull]{.figtext}. -Если команда выполнилась успешно, в списке файлов появится файл `README.md`, -а в журнале --- коммит созданный через GitHub. +::: {.clearfix} +::: Как и в случае с переключением веток, Git откажется загружать изменения и выдаст ошибку, если в рабочей папке имеются незафиксированные изменения, которые конфликтуют с загружаемыми. diff --git a/docs/04-04-pull-request.md b/docs/04-04-pull-request.md index 71ab9a6..c254b02 100644 --- a/docs/04-04-pull-request.md +++ b/docs/04-04-pull-request.md @@ -4,51 +4,50 @@ Pull Request --- это механизм GitHub для слияния веток Орнитолог проходящий мимо нашего репозитория обратит внимание, что длину клюва пингвина лучше рассматривать в зависимости от пола. Он даже может предложить необходимые изменения при помощи Pull Request. -Создайте ветку с названием `adjust-by-sex` при помощи кнопки [New branch]{.figtext} на панели [Git]{.figtext} в RStudio. Убедитесь, что справа от кнопки вместо названия ветки по умолчанию `main` выводится название созданной ветки `adjust-by-sex`. +Создайте ветку с названием `adjust-by-sex`, как показано в [разделе «Создание ветки»](#git-branch): нажмите `main`в строке состояния Positron и выберите [Create new branch…]{.figtext} Убедитесь, что вместо `main` выводится название созданной ветки `adjust-by-sex`. -![](./img/04-04-01-add-branch.png){width=200} +Замените код в чанке на приведённый ниже. Чтобы посмотреть, что изменилось, выберите файл `paper.qmd` на панели [Source Control]{.figtext}. -Отредактируйте скрипт `penguins.R`, добавив пол в код для построения ящика с усами. Код приведен ниже, не забывайте, что вы можете сравнить изменения по сравнению с оригиналом при помощи кнопки [Diff]{.figtext} на панели [Git]{.figtext}. -```r -data <- read.csv("penguins.csv") -x <- data$bill_length_mm +``` r +data <- read.csv("data/penguins.csv") + +x <- data$bill_len g <- data$sex -png("penguins-boxplot.png") boxplot(x ~ g, xlab = "Sex", ylab = "Bill length, mm") -dev.off() ``` -Сохраните и выполните скрипт `penguins.R`. -Создайте коммит включив в него скрипт и обновленную диаграмму `penguins-boxplot.png`. +Сохраните файл и нажмите [Preview]{.figtext}, чтобы обновить отчёт. +Создайте коммит, включив в него `paper.qmd` и `paper.html`. +После создания коммита выберите [Publish Branch]{.figtext} на панели [Source Control]{.figtext}. -![](./img/04-04-02-git-commit.png){width=100%} +![](./img/SCR-20260830-ejim.png){width=100%} -После создания коммита нажмите кнопку [Push]{.figtext} в верхнем правом углу или на панели [Git]{.figtext}. Так как у вас полные права на редактирование репозитория, то новая ветка будет загружена на GitHub. Прохожему орнитологу пришлось бы создать свою копию репозитория или просить дать доступ средствами GitHub. +Так как у вас полные права на редактирование репозитория, то новая ветка будет загружена на GitHub. +Прохожему орнитологу пришлось бы создать свою копию репозитория или просить дать доступ средствами GitHub. -Перейдите на страницу репозитория в GitHub и убедитесь, что ветка была загружена и содержит сделанные измнения, для этого выберите ее в выпадающем меню появляющемся при нажатии кнопки с названием ветки [main]{.figtext}. +Перейдите на страницу репозитория в GitHub и убедитесь, что ветка содержит сделанные измнения, для этого выберите ее в выпадающем меню появляющемся при нажатии кнопки с названием ветки [main]{.figtext}. -![](img/04-04-03-github-branch.png){width=100%} +![](./img/SCR-20260830-ekqj.png){width=100%} При просмотре ветки отличной от основной, GitHub предложит создать из нее **Pull Request** --- предложение автору репозитория слить изменения из этой ветки. Нажмите кнопку [Contribute]{.figtext} и в выпадающем меню выберите [Open pull request]{.figtext}. -![](img/04-04-04-github-pr.png){width=100%} +![](./img/SCR-20260830-ektf.png){width=100%} GitHub предложит ввести заголовок и описание предлагаемых изменений, правило хорошего тона кратко описать причину изменений и суть предлагаемого решения. А также, прокрутите страницу создания Pull Request и проверьте изменения, которые вы предлагаете, после чего нажмите кнопку [Create pull Request]{.figtext} под полем с описанием. -![](img/04-04-05-github-pr.png){width=100%} +![](./img/SCR-20260830-elgi.png){width=100%} На странице Pull Request владельцу репозитория доступна опция слить предложенные изменения. Нажмите кнопку [Merge pull request]{.figtext} внизу страницы. -В открывшемся окне GitHub предложить ввести текст коммита, как если бы мы делали слияние ветки в терминале. Оставьте или измените текст и нажмите кнопку [Confirm merge]{.figtext} +В открывшемся окне GitHub предложить ввести текст коммита, как если бы мы делали слияние ветки в Positron. Оставьте или измените текст и нажмите кнопку [Confirm merge]{.figtext} После успешного слияния ветку можно удалить. ![](img/04-04-06-merge-pr.png){width=100%} ![](img/04-04-07-merge-pr.png){width=100%} ![](img/04-04-08-merge-pr.png){width=100%} -Вернемся к нашему проекту в RStudio. -Слияние было выполнено онлайн на GitHub, а значит необходимо загрузить изменения в наш локальный репозиторий, т.е. сделать pull. -Переключитесь на ветку `main` при помощи панели [Git]{.figtext} и нажмите кнопку [Pull]{.figtext}. -Убедитесь, что теперь ветка `main` содержит актуальные изменения в файлах `penguins.R` и `penguins-boxplot.png`. +Вернёмся к проекту в Positron. Мы выполнили слияние на GitHub, поэтому локальный репозиторий ещё не содержит новых изменений. +Переключитесь на `main` при помощи строки состояния и загрузите изменения, как в [предыдущей главе](#git-push-pull), нажав [Pull]{.figtext}. +Убедитесь, что файлы `paper.qmd` и `paper.html` обновились. diff --git a/docs/04-05-clone.md b/docs/04-05-clone.md index f22c4ab..f023465 100644 --- a/docs/04-05-clone.md +++ b/docs/04-05-clone.md @@ -10,25 +10,14 @@ Нажмите кнопку [Code]{.figtext} на странице репозитория, убедитесь что выбрана опция **HTTPS** и скопируйте адрес. -![](./img/04-03-05-new-project.png){width="600px"} +![Меню Code на GitHub: выбрана вкладка HTTPS и показан адрес репозитория. Откройте опубликованный репозиторий и нажмите Code]() -Создадим проект RStudio. -В верхнем меню выберите [File → New Project]{.figtext}. -В появившемся окне выберите [Version Control]{.figtext} и далее [Git]{.figtext}. -В поле [Repository URL]{.figtext} вставьте адрес репозитория. -В поле [Project directory name]{.figtext} укажите название папки для проекта --- -т.к. папка `penguins` уже существует, используем название `penguins2`. -Откроется окно проекта, RStudio готова к работе. +Создадим копию проекта в Positron. +Откройте новое окно без проекта и в палитре команд выберите [Workspaces: New Folder from Git…]{.figtext}. +Выберите [Clone from GitHub]{.figtext} и свой репозиторий `r-course` или вставьте скопированный адрес. +Укажите другую родительскую папку, чтобы новая копия не оказалась внутри уже открытого проекта. +После загрузки нажмите [Open]{.figtext}. - - - - - - - - - -
![](./img/04-03-01-new-project.png){width="320px"}![](./img/04-03-02-new-project.png){width="320px"}
![](./img/04-03-03-new-project.png){width="320px"}![](./img/04-03-04-new-project.png){width="320px"}
+![Окно Workspaces: New Folder from Git в Positron: выбран репозиторий r-course и папка для новой копии. Выполните Workspaces: New Folder from Git… в новом окне Positron]() Мы склонировали удаленный репозиторий на компьютер и теперь можем работать с ним как с оригинальным проектом --- делать коммиты, загружать изменения в удаленный репозиторий (push) и из него (pull). diff --git a/docs/04-06-conclusion.md b/docs/04-06-conclusion.md index bf1b66e..74990b2 100644 --- a/docs/04-06-conclusion.md +++ b/docs/04-06-conclusion.md @@ -7,7 +7,7 @@ Диаграмма ниже поможет запомнить как соотносятся действия, которые мы изучили: [1) создание коммитов](#git-commit), [2) работа с ветками](#branch) и [3) синхронизация с удаленным репозиторием](#git-push-pull). -![](./img/04-06-sequence.png){width=100%} +![Связь коммитов, веток и синхронизации с удалённым репозиторием](./img/04-06-sequence.png){width=100%} Рекомендуем использовать Git в своих проектах и не бояться экспериментировать с ветками. Это помогает структурировать рабочий процесс, делает анализ данных воспроизводимым и облегчает командную работу. diff --git a/docs/05-01-faq.md b/docs/05-01-faq.md index 128bc53..e3b9840 100644 --- a/docs/05-01-faq.md +++ b/docs/05-01-faq.md @@ -34,7 +34,7 @@ ::: Создайте новую ветку - она будет содержать набор коммитов, который вы имеете сейчас, -при помощи RStudio или командой ниже. +при помощи Positron или командой ниже. ```sh git branch some @@ -42,7 +42,7 @@ git branch some Важно! Убедитесь в том, что создали ветку. Для этого посмотрите журнал или команду `git log` и найдите напротив текущего коммита надпись с названием созданной ветки. -Вернитесь на оригинальную ветку, как правило это `main`, при помощи RStudio или команды ниже. +Вернитесь на оригинальную ветку, как правило это `main`, при помощи Positron или команды ниже. ```sh git checkout main diff --git a/docs/05-02-references.md b/docs/05-02-references.md index b1460ee..4d30e57 100644 --- a/docs/05-02-references.md +++ b/docs/05-02-references.md @@ -1,5 +1,8 @@ # Ссылки {#references} +- [Документация Positron](https://positron.posit.co/welcome.html) --- официальное руководство по интерфейсу Positron. +- [Git Version Control](https://positron.posit.co/git.html) --- работа с Git в Positron. +- [Quarto](https://positron.posit.co/quarto.html) --- работа с документами `.qmd` в Positron. - [Pro Git](https://git-scm.com/book/en/v2) --- небольшая книга рекомендованная разработчиками Git. Из нее вы узнаете о внутреннем устройстве Git и научитесь работать с командой `git` в терминале. Пригодятся главы 1-3 и глава 6. - [Happy Git and GitHub for the useR](https://happygitwithr.com/) --- материалы практического курса по Git с конференции Posit. - [Git Cheatsheet](https://ndpsoftware.com/git-cheatsheet.html#loc=local_repo;) - интерактивная шпаргалка. diff --git a/docs/05-03-webhooks.md b/docs/05-03-webhooks.md index eae5442..24e6d3e 100644 --- a/docs/05-03-webhooks.md +++ b/docs/05-03-webhooks.md @@ -6,7 +6,7 @@ GitHub отправит информацию о событии на указан Для обработки событий по указанному адресу должна работать программа (веб-сервер). Многие сервисы, например Slack или Microsoft Teams, поддерживают таким образом отправку уведомлений в рабочий чат. -Для Telegram можно воспользоваться ботом [@octo8bot](https://t.me/octo8bot). +Для Telegram можно воспользоваться ботом [\@octo8bot](https://t.me/octo8bot). Добавьте бота в чат и скопируйте присланный им адрес. diff --git a/docs/404.html b/docs/404.html index 10a7360..54e6323 100644 --- a/docs/404.html +++ b/docs/404.html @@ -1,57 +1,34 @@ - + - - - - Page not found | Основы Git - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + -
-
+

Page not found +

The page you requested cannot be found (perhaps it was moved or renamed).

You may want to try searching to find the page's new location, or use the table of contents to find the page you are looking for.

-
- - +
+
+
+
-
-
+

This book was built by the bookdown R package.

-
- - - +
- diff --git a/docs/about.html b/docs/about.html index 05e104b..aa61088 100644 --- a/docs/about.html +++ b/docs/about.html @@ -17,7 +17,7 @@ - +