Документация Engee
Notebook

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

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

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

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

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

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

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

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

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

In [ ]:
@doc sqrt
Out[0]:
sqrt(x)

Возвращает $\sqrt{x}$. Выдает ошибку DomainError при отрицательных аргументах типа Real. Используйте вместо этого комплексные отрицательные аргументы. Префиксный оператор эквивалентен sqrt.

См. также описание hypot.

Примеры

jldoctest;
julia> sqrt(big(81))
9.0

julia> sqrt(big(-81))
ERROR: DomainError with -81.0:
NaN result for non-NaN input.
Stacktrace:
 [1] sqrt(::BigFloat) at ./mpfr.jl:501
[...]

julia> sqrt(big(complex(-81)))
0.0 + 9.0im

julia> .√(1:4)
4-element Vector{Float64}:
 1.0
 1.4142135623730951
 1.7320508075688772
 2.0
sqrt(A::AbstractMatrix)

Если матрица A не имеет отрицательных вещественных собственных значений, вычисляет натуральный квадратный корень матрицы A, то есть уникальную матрицу $X$ с собственными значениями, имеющими положительную вещественную часть, так что $X^2 = A$. В противном случае возвращается ненатуральный квадратный корень.

Если матрица A является симметричной или эрмитовой, для вычисления квадратного корня используется ее разложение по собственным значениям (eigen) . Для таких матриц собственные значения λ, которые из-за ошибок округления кажутся слегка отрицательными, рассматриваются как нулевые. Более точно, матрицы со всеми собственными значениями ≥ -rtol*(max |λ|) рассматриваются как полубесконечные (выдающие эрмитов квадратный корень), а отрицательные собственные значения принимаются за нуль. rtol является именованным аргументом для sqrt (только для эрмитовых или вещественно-симметричных матриц), который по умолчанию имеет машинную точность, масштабированную на size(A,1).

В противном случае квадратный корень определяется с помощью метода Бьорка-Хаммарлинга [^BH83], который вычисляет комплексную форму Шура (schur), а затем — комплексный квадратный корень треугольного множителя. Если вещественный квадратный корень существует, используется расширение этого метода [^H87], которое вычисляет вещественную форму Шура, а затем — вещественный квадратный корень квазитреугольного множителя.

[^BH83]: Åke Björck and Sven Hammarling, "A Schur method for the square root of a matrix", Linear Algebra and its Applications, 52-53, 1983, 127-140. doi:10.1016/0024-3795(83)80010-X80010-X)

[^H87]: Nicholas J. Higham, "Computing real square roots of a real matrix", Linear Algebra and its Applications, 88-89, 1987, 405-430. doi:10.1016/0024-3795(87)90118-290118-2)

Примеры

jldoctest
julia> A = [4 0; 0 4]
2×2 Matrix{Int64}:
 4  0
 0  4

julia> sqrt(A)
2×2 Matrix{Float64}:
 2.0  0.0
 0.0  2.0

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

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

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]:

Краткое описание функции, здоровающейся с пользователем

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

В LaTex мы используем $\nu$ для обозначения символа ню: $\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]:

Документация, содержащая:

  1. Markdown:

  2. Встроенный $\LaTeX$ (inline) $\frac{\sqrt{\pi}}{2}$ и отдельной формулой:

$$ \int \limits_{-\infty}^\infty e^{-x^2}\,dx = \sqrt{\pi} $$

Смотреть также

документирование, функции

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

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

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

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]:

Ускорение свободного падения

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

Ускорение свободного падения

Обратите внимание, что 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

GeometricShape((x=X,y=Y),α)

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

Пример:

GeometricShape((x=1., y=2.), 3.)

Возможные ошибки

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.)

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.)

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]:

Макрос, здоровающийся с пользователем

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

В папке вместе с этим примером находится файл 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]:

Модуль перевода температур. Поддерживает шкалы:

  • Фаренгейта
  • Цельсия

Основные функции:

fahr2cels, cels2fahr,

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

In [ ]:
@doc fahr2cels
Out[0]:
fahr2cels(t_f::Real)

Преобразует число t_f из шкалы Фаренгейта в шкалу Цельсия по формуле

$$ \frac{5}{9}(t_f+32) $$

fahr2cels(t_f::String)

Сначала преобразует строку в число, затем конвертирует.

Extended help

Здесь мы можем указать более подробную документацию

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

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

? fahr2cels

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

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

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

?? fahr2cels

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

Выводы

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

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