Сообщество Engee

Документирование кода в Engee

Автор
avatar-igarajaigaraja
Notebook

Документация и документирование в Engee

Хорошая документация - залог качественного понимания и использования кода.
Язык Julia позволяет удобно пользоваться и создавать документацию "из коробки".

В данном нотбуке будут рассмотрены:

  • получение справки в .ngscript
  • получение справки в командной строке
  • создание собственной документации для
    • функций
    • глобальных переменных
    • структур
    • модулей

Также будет рассмотрен способ создания и подключения собственного модуля.

Получение справки в .ngscript

Для получения справки в .ngscript необходимо воспользоваться макросом @doc

Рассмотрим получение справки для sqrt.

Обратите внимание на использование в документации Markdown, и подстветку синтаксиса.

In [ ]:
@doc sqrt
Out[0]:

@doc sqrt

Получение справки в командной строке

Для получения справки в командной строке используйте вопросительный знак: ?

screenshot_2024_11_21_135151.png

Если хотите РАСШИРИТЬ свои знания про использование командной строки - дочитайте документ до конца 😊😊😊.

Создание собственной документации

Документирование функций.

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

Если описание функции длинное, то рекомендуется использовать тройные двойные кавычки.

In [ ]:
"Краткое описание функции, здоровающейся с пользователем"
function user_greeting(username::String)
    return "Hello, $(username)!"
end
Out[0]:
user_greeting
In [ ]:
@doc user_greeting
Out[0]:

@doc user_greeting

Кратко рассмотрим, почему для того чтобы использовать символы \ и $ мы используем raw - литерал необработанных строк:

В LaTex мы используем $\nu$ для обозначения символа ню:

Здесь сразу может возникнуть множество проблем. Внутри " "

Поэтому "$\nu$" не сможет быть корректно выполнено. Однако эту проблему можно решить, используя raw-строки

In [ ]:
# "$\nu$" # вызовет ошибки
In [ ]:
@show raw"$\nu$";
raw"$\nu$" = "\$\\nu\$"
In [ ]:
@doc raw"""
Документация, содержащая:

1. Markdown:
    - маркеры списка
    - [внешние ссылки](https://engee.com/helpcenter/stable/ru/julia/stdlib/Markdown.html)

2. Встроенный $\LaTeX$ (inline) $\frac{\sqrt{\pi}}{2}$  и отдельной формулой:
```math
\int \limits_{-\infty}^\infty e^{-x^2}\,dx = \sqrt{\pi}
```
## Смотреть также

[`документирование`](https://engee.com/helpcenter/stable/ru/julia/manual/documentation.html
), [`функции`](https://engee.com/helpcenter/stable/ru/julia/manual/functions.html)
"""
function foo()
    return nothing
end
Out[0]:
foo
In [ ]:
@doc foo
Out[0]:

@doc foo

Документирование глобальных переменных

При использовании глобальных переменных, помните о вопросах производительности и целесообразности их использования

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

In [ ]:
"Ускорение свободного падения"
g_Earth, g_Moon
const g_Earth::Float64 = 9.81
const g_Moon::Float64 = 1.62
Out[0]:
1.62

Теперь проверим, что сразу для двух переменных существует одинаковая справка:

In [ ]:
@doc g_Earth
Out[0]:

@doc g_Earth

In [ ]:
@doc g_Moon
Out[0]:

@doc g_Moon

Обратите внимание, что const означает константность типа переменной, но не её значения.

  • При изменении типа будет вызвана ОШИБКА
  • При изменении на значение того же типа будет выведено ПРЕДУПРЕЖДЕНИЕ
In [ ]:
# g_Moon = "Moon"
In [ ]:
println(g_Earth)
g_Earth = 32.
println(g_Earth)
9.81
32.0
WARNING: redefinition of constant Main.g_Earth. This may fail, cause incorrect answers, or produce other errors.

Документирование структур

Пускай имеется набор одинаковых фигур.

Задача состоит в том, чтобы расположить фигуры на плоскости наиболее компактным образом. Тогда структура будет содержать центр масс и угол поворота фигуры относительно горизонтали.
В качестве конструктора по умолчанию выберем GeomteryShape((x=0,y=0),α=0). Подробнее про конструкторы можно прочитать в документации.

In [ ]:
@doc """
GeometricShape((x=X,y=Y),α)

    Геометрическая фигура
- `center_of_mass`: (x=X,y=Y) - кортеж координат центра масс
- `orientation`: α - угол поворота фигуры относительно горизонтали
## Пример:
GeometricShape((x=1., y=2.), 3.)

## Возможные ошибки
1.
```julia-repl
julia> GeometricShape((4.,5.),6.)
ERROR: MethodError: no method matching GeometricShape(::Tuple{Float64, Float64}, ::Float64)

Closest candidates are:
  GeometricShape(::@NamedTuple{x::Float64, y::Float64}, ::Any)
```
**Решение:** в кортеже нужно явно указать имена полей: `GeometricShape((x=4., y=5.), 6.)`
2. 
```julia-repl
julia> GeometricShape((x=1,y=2),3.)
ERROR: MethodError: no method matching GeometricShape(::@NamedTuple{x::Int64, y::Int64}, ::Float64)

Closest candidates are:
  GeometricShape(::@NamedTuple{x::Float64, y::Float64}, ::Any)
```
**Решение:** передавайте в качетсве параметров значения типа `Float64`, а не `Int64`: GeometricShape((x=1.,y=2.),3.)
"""
struct GeometricShape
    center_of_mass::NamedTuple{(:x,:y),Tuple{Float64,Float64}}
    orientation::Float64
    GeometricShape() = new((x=0,y=0),0)  # конструктор по умолчанию
    GeometricShape((X,Y)::NamedTuple{(:x,:y),Tuple{Float64,Float64}},α)=new((x=X,y=Y),α)
end
GeometricShape
In [ ]:
GeometricShape((x=4.,y=5.),6.)
GeometricShape((x = 4.0, y = 5.0), 6.0)
In [ ]:
@doc GeometricShape

@doc GeometricShape

In [ ]:
GeometricShape()
GeometricShape((x = 0.0, y = 0.0), 0.0)
In [ ]:
first_shape = GeometricShape((x=1.,y=2.),3.)
first_shape.center_of_mass.y
2.0

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

In [ ]:
# first_shape.orientation = 4. # ОШИБКА: нельзя менять уже созданный объект

Документирование макросов

In [ ]:
"Макрос, здоровающийся с пользователем"
macro hellouser(username)  # создание макроса
println("Hello, $(username)!")
end

@hellouser "Peter"  # применение макроса
Hello, Peter!

Чтобы получить справку для макроса, нужно сначала написать @, а затем ввести имя макроса:
@macrosname

In [ ]:
@doc @hellouser
Out[0]:

@doc @hellouser

Создание и документирование модуля

В папке вместе с этим примером находится файл TemperatureScales.jl. Этот файл содержит в себе модуль TemperatureScales.

Чтобы получить доступ к его функциям и переменным, необходимо

  1. перейти в папку с помощью команды cd(path), где находится выполняемый файл (documentating.ngscript) (@__DIR__). По этому же пути содержится TemperatureScales.jl:
In [ ]:
@__DIR__
Out[0]:
"/user/Engee/Demos/Engee/Documentating"
In [ ]:
cd(@__DIR__)
  1. Включить этот модуль в наш скрипт:
    Выполнив команду include("Filename.jl"), julia "включит" текст из файла Filename.jl в наш текущий скрипт и выполнит его. (Посмотрите на 1ю строчку файла TemperatureScales.jl). А значит объекты из этого файла станут объектами нашего файла.
In [ ]:
include("TemperatureScales.jl")
Greeting from TemperatureScales.jl!
Out[0]:
Main.TemperatureScales
In [ ]:
println(variable_from_TemperatureScales)
3

Но наша задача - использовать модуль из этого файла. Модуль создаётся при помощи ключевого слова module, а используется при помощи using или import.

In [ ]:
using .TemperatureScales

Чтобы узнать, что именно этот модуль делает - вызовем справку об этом модуле:

In [ ]:
@doc TemperatureScales
Out[0]:

@doc TemperatureScales

Узнаем, как работают функции fahr2cels:

In [ ]:
@doc fahr2cels
Out[0]:

@doc fahr2cels

Как видно, справка по fahr2cels указывает 2 метода. Первый, когда аргументом является число, а второй - когда аргументом является строка.

Теперь перейдите в командную строку и выполните

? fahr2cels

Обратите внимание на последнюю строчку:
Extended help is available with ??.

Теперь выйдите из режима справки (удалив ?)

И теперь введите

?? fahr2cels

Теперь мы получили РАСШИРЕННУЮ справку 😊😊😊.

Выводы

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

Было рассмотрено включение пользовательского модуля в скрипт.